2013-06-05 68 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

偉大的用戶名。無論如何,正如我在電子郵件中提到的那樣,它會轉變,但新項目處於最終狀態。對於視頻來說,當它轉換到下一個項目時,它會卡在最後一幀。 –