2013-12-09 2 views
4

Я установил ContentControl в правой части окна и задал элементы привязки контента (это тип ObservableCollection). Теперь я хочу достичь этого: если нет элемента, ContentControl выбирает первый DataTemplate и добавляет элемент в элементы, ContentControl будет выбирать второй DataTemplate для отображения некоторой информации.ContentControl.ContentTemplateSelector динамически выбирает шаблон

Как это:

enter image description here

Проблема заключается в том, когда я добавить один пункт в элементы, ContentControl didnot обновление и изменение DataTemplate, я попробовать режим, UpdateSourceTrigger и т.д. установлен, но не удалось. В ViewModel, после удаления элемента, я использую эти заявления, он будет хорошо работать < 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

Вы реализовали «интерфейс INotifyPropertyChanged' в вашей модели представления и для' 'деталей собственности? – Sheridan

+1

Я использую mvvmlight. Класс MyViewModel наследуется от ViewModelBase. ViewModelBase: ObservableObject: INotifyPropertyChanged. – SubmarineX

ответ

7

ContentControl будет только слушать PropertyChanged события и не для CollectionChanged события. Для этого необходимо использовать либо ItemsControl, либо любую другую его версию, например ListView.

В качестве обходного пути, вы можете создать Style для ContentControl и вместо TemplateSelector, определить DataTrigger на Items.Count и установите 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

Смежные вопросы