2013-06-05 119 views
1

我工作的一个数字标牌WPF应用程序和基础结构的设置如下:WPF MVVM的DataTemplates - 景观更新

我有一个网格,它绑定到一个播放列表对象的单一视图。播放列表包含窗格,窗格包含播放列表项目,播放列表项目每个都包含一个内容项目。我使用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> 

随着datacontext的更改,每个窗格中的内容会从一个项目转换到下一个项目。我遇到了一个问题,用户在同一个窗格中连续放置两个相同的项目,无论是视频,图像等。发生的变化是未检测到更改,UI不更新。在视频的情况下,它冻结在第一个视频的最后一帧,整个应用程序挂起。

我曾尝试PlaylistItem类中做一个OnPropertyChanged(“ContentItem”),尝试设置共享我的数据模板=“false”时,我尝试了ContentItem对象上更改属性和提高的PropertyChanged事件,似乎没有任何工作。我打开了数据绑定的跟踪,看看发生了什么,它看起来似乎正常工作。当我更改ContentItem上的属性时,它会为新项目显示一个新的散列,但在UI上不会更改。

内TransitionableContentControl在PlaylistItem,从一个内容项去同一个时OnContentChanged倍率从不打。如果我将该控件与常规ContentControl交换,则不会更改。

+0

您是否尝试将模式从'OneTime'改为'OneWay'? –

+0

是的,没有任何效果 –

+0

如果你能以某种方式提供再现问题的样本项目,我将很乐意进一步调查此。 – Stipo

回答

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) ; 
})) ; 
+0

这也没有任何影响。它不按原样编译,我将其更新为使用DispatcherPriorty,Action重载并对应用程序没有影响。我也尝试将PlaylistItem的ContentItem设置为一个新的空对象并且没有改变。 –

+0

是的,忘了粘贴在我的测试应用程序的补充。当然,它没有效果:因为OnPropertyChanged没有被调用,所以WPF从来不知道该属性已经改变。 –

1

这里的问题是ContentControl中(或者说潜在的DependencyProperty框架)不火OnContentChanged时.Equals是新老内容真实。一种解决方法是在CoerceValue上拥有自己的依赖项属性和转换。我会通过电子邮件发送给你的代码,你可以在这里发布。

+0

伟大的用户名。无论如何,正如我在电子邮件中提到的那样,它会转变,但新项目处于最终状态。对于视频来说,当它转换到下一个项目时,它会卡在最后一帧。 –