[英]ContentControl.ContentTemplateSelector dynamically select template
I set a ContentControl in the right of Window, and set Content binding Items (it's type is ObservableCollection). 我在Window的右边设置了一个ContentControl,并设置了内容绑定项(它的类型是ObservableCollection)。 Now I want to achieve it: if there are no item, ContentControl select first DataTemplate, and add a item into items, ContentControl will select second DataTemplate to display some info.
现在我想实现它:如果没有项目,ContentControl选择第一个DataTemplate,并将项目添加到项目中,ContentControl将选择第二个DataTemplate来显示一些信息。
Like this: 像这样:
The problem is when I add one item into items, ContentControl didnot update and change DataTemplate, I have a try to set mode, UpdateSourceTrigger, etc., but failed. 问题是当我在项目中添加一个项目时,ContentControl没有更新和更改DataTemplate,我尝试设置模式,UpdateSourceTrigger等,但失败了。 In ViewModel, after delete a item, I use this statements, it will work well <1> :
在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;
}
}
Edited: use this way is also failed after delete one item: 编辑:使用这种方式删除一项后也失败:
RaisePropertyChanging(ItemsPropertyName);
RaisePropertyChanged(ItemsPropertyName);
but I wonder why it work well with <1> . 但我想知道为什么它适用于<1> 。
Edited2 It's the delcaration: 编辑2这是蜕变:
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);
}
}
ContentControl
will listen only for PropertyChanged
events and not for CollectionChanged
event. ContentControl
将仅侦听PropertyChanged
事件,而不侦听CollectionChanged
事件。 You'll need to use either an ItemsControl
or any of its other versions like ListView
for this behavior. 您需要使用
ItemsControl
或其他任何版本(如ListView
来执行此操作。
As a workaround, you can create a Style
for the ContentControl
and instead of TemplateSelector
, define a DataTrigger
on Items.Count
and set the ContentTemplate
accordingly. 作为解决方法,您可以为
ContentControl
创建Style
,而不是TemplateSelector
,在DataTrigger
上定义Items.Count
并相应地设置ContentTemplate
。 Something like, 就像是,
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.