1

私はデジタルサイネージ WPF アプリケーションに取り組んでおり、基本的な構造は次のように設定されています。

プレイリスト オブジェクトにバインドされたグリッドを含む単一のビューがあります。プレイリストにはペインが含まれ、ペインにはプレイリスト アイテムが含まれ、プレイリスト アイテムにはそれぞれコンテンツ アイテムが含まれます。DataTemplates を使用して、各部分のビューを構築します。

    <!-- This template represents a single content pane, no real display here, just empty space with a height and width -->
    <DataTemplate DataType="{x:Type entities:ContentPane}">
        <ContentControl 
            Content="{Binding CurrentPlaylistItem, Mode=OneWay}" 
            Height="{Binding Height, Mode=OneTime}" 
            Width="{Binding Width, Mode=OneTime}" 
            HorizontalAlignment="Left"
            VerticalAlignment="Top"                
            />
    </DataTemplate>

    <!-- This is a playlist item which is contained within a ContentPane.
         This also has no real display, just a placeholder for the content item, and will likely contain some transition information-->
    <DataTemplate DataType="{x:Type entities:PlaylistItem}">
        <inf:TransitionableContentControl Content="{Binding ContentItem}"></inf:TransitionableContentControl>
    </DataTemplate>


    <!-- image item template 
         the path can be any valid uri e.g. http://... or file://... -->
    <DataTemplate DataType="{x:Type contentTypes:ImageContentType}">
        <Grid Background="Transparent" x:Name="ImageType">
            <Image Source="{Binding Bitmap, Mode=OneTime}"></Image>
            <inf:BusinessAd
                        ContainerHeight="{Binding ImageHeight, Mode=OneTime}"
                        ContainerWidth="{Binding ImageWidth, Mode=OneTime}"                            
                        Visibility="{Binding AdText, Converter={StaticResource _VisibilityConverter}, Mode=OneWay}"
                        Text="{Binding AdText.Text, Mode=OneTime}"
                        AdFontSize="{Binding AdText.TextStyle.FontSize}"
                        AdFontFamily="{Binding AdText.TextStyle.FontFamily}">
                <ContentControl 
                    Content="{Binding AdText, Mode=OneTime}"                         
                    ContentTemplate="{StaticResource BusinessAdTextTemplate}">
                </ContentControl>
            </inf:BusinessAd>
        </Grid>
    </DataTemplate>

データ コンテキストが変化すると、各ペインのコンテンツが 1 つの項目から次の項目に移行します。ビデオ、画像など、ユーザーが同じ項目をペインに 2 回続けて配置するという問題が発生しています。変更が検出されず、UI が更新されません。ビデオの場合、最初のビデオの最後のフレームでフリーズし、アプリケーション全体がハングします。

PlaylistItem クラス内で OnPropertyChanged("ContentItem") を実行してみました。データ テンプレートで Shared="False" を設定してみました。ContentItem オブジェクトのプロパティを変更して PropertyChanged イベントを発生させてみましたが、何も機能していないようです。データバインディングのトレースをオンにして、何が起こっているかを確認しましたが、すべて正しく機能しているようです。ContentItem のプロパティを変更すると、新しいアイテムの新しいハッシュが表示されますが、UI は変更されません。

PlaylistItem の TransitionableContentControl 内では、あるコンテンツ アイテムから同じアイテムに移動するときに OnContentChanged オーバーライドがヒットすることはありません。そのコントロールを通常の ContentControl に交換しても、変化はありません。

4

2 に答える 2

1

診断については元従業員が正しい。さらに、お気づきのように、内部データコンテキストを再割り当てしない限り、テンプレートは最初から再開されません。最初にデフォルトの空のアイテムに割り当てて、CurrentPlaylistItemすべてをリセットする必要があります。競合や厄介なちらつきを避けるには、UI レンダリングよりもディスパッチャーの優先度を高くしてください。これを試して:

// CurrentPlaylistItem = pli ; -- not good
Application.Current.Dispatcher.Invoke (new Action (() =>
{
    // clear item
    // null doesn't work, because TransitionableContentControl's
    // inner ContentControl would be empty and the brush created 
    // from it would be a null brush (no visual effect)
    CurrentPlaylistItem = new PlaylistItem () ;
    this.OnPropertyChanged ("CurrentPlaylistItem") ;
    Application.Current.Dispatcher.Invoke (new Action (() =>
    {
        // set new item, possibly same as old item
        // but WPF will have forgotten that because
        // data bindings caused by the assignment above
        // have already been queued at the same DataBind 
        // level and will execute before this assignment
        CurrentPlaylistItem = pli ; 
        this.OnPropertyChanged ("CurrentPlaylistItem") ;
    }), DispatcherPriority.DataBind) ;
})) ;
于 2013-06-09T18:13:31.147 に答える