2013-12-09 167 views
4

我在Window的右邊設置了一個ContentControl,並設置了Content binding Items(它的類型是ObservableCollection)。現在我想實現它:如果沒有項目,ContentControl會選擇第一個DataTemplate,並將項目添加到項目中,ContentControl將選擇第二個DataTemplate來顯示一些信息。ContentControl.ContentTemplateSelector動態選擇模板

像這樣:

enter image description here

問題是,當我加入一個項目到項目,ContentControl中因此未更新和更改DataTemplate中,我有一個嘗試設置模式,UpdateSourceTrigger等,但失敗了。在視圖模型,之後刪除一個項目,我用這個語句,它會工作得很好< 1>

private void ExecuteDeleteClientCommand() 
{ 
    ... 
    if (DeleteClient(item)) 
    { 
     ObservableCollection<MyViewModel> tmp = TabItems; 
     TabItems = null; 
     TabItems = tmp; 
    } 
} 

<ContentControl 
    ContentTemplateSelector="{StaticResource MyDataTemplateSelector}" 
    Content="{Binding Items}"/> 

public class SingleClientDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, 
     DependencyObject container) 
    { 
     ObservableCollection<MyViewModel> obj = 
      item as ObservableCollection<MyViewModel>; 
     if (null == obj || 0 == obj.Count) 
     { 
      return App.Current.FindResource("NullItemDataTemplate") as DataTemplate; 
     } 
     return App.Current.FindResource("DefaultDataTemplate") as DataTemplate; 
    } 
} 

編輯: 使用這種方式也未能刪除一個項目後:

RaisePropertyChanging(ItemsPropertyName); 
RaisePropertyChanged(ItemsPropertyName); 

,但我不知道爲什麼它< 1>很好地工作。

Edited2 這是delcaration:

public const string ItemsPropertyName = "Items"; 
private ObservableCollection<MyViewModel> items = new ObservableCollection<MyViewModel>(); 
public ObservableCollection<SingleClientDetailViewModel> TabItems 
{ 
    get { return items; } 
    set 
    { 
     if (items == value) { return;} 
     RaisePropertyChanging(ItemsPropertyName); 
    items = value; 
    RaisePropertyChanged(ItemsPropertyName); 
    } 
} 
+0

你有沒有實現您的視圖模型,爲'Items'屬性「INotifyPropertyChanged'接口? – Sheridan

+1

我使用mvvmlight。 MyViewModel類繼承自ViewModelBase。 ViewModelBase:ObservableObject:INotifyPropertyChanged。 – SubmarineX

回答

7

ContentControl將監聽CollectionChanged事件只爲PropertyChanged事件,而不是。對於此行爲,您需要使用ItemsControl或其他任何版本,如ListView

作爲一種變通方法,您可以創建爲ContentControl一個Style和替代TemplateSelector,定義上Items.Count一個DataTrigger並設置相應ContentTemplate。 喜歡的東西,

 <ContentControl Content="{Binding Items}"> 
     <ContentControl.Style> 
      <Style TargetType="ContentControl"> 
       <Setter Property="ContentTemplate" Value="{StaticResource DefaultDataTemplate}" /> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Path=Items}" Value="{x:Null}"> 
         <Setter Property="ContentTemplate" Value="{StaticResource NullItemDataTemplate}" /> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding Path=Items.Count}" Value="0"> 
         <Setter Property="ContentTemplate" Value="{StaticResource NullItemDataTemplate}" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </ContentControl.Style> 
    </ContentControl> 
+0

謝謝,這種方式很好。但我仍然不知道爲什麼它不工作,當我手動調用'RaisePropertyChanged(ItemsPropertyName)'在這種情況下:現在Items.Count是1,我刪除唯一的一個項目並調用RaisePropertyChanged(ItemsPropertyName)。 – SubmarineX

+0

您確定'ItemsPropertyName'的值是'string'值'Items'而不是null。您沒有提供該財產的財產聲明,因此無法對此作進一步評論。 –

+0

請參閱Edited2。 – SubmarineX