问题描述
我在Window的右边设置了一个ContentControl,并设置了Content binding Items(它的类型是ObservableCollection).现在我想实现它:如果没有项目,ContentControl选择第一个DataTemplate,并在项目中添加一个项目,ContentControl将选择第二个DataTemplate显示一些信息.
I set a ContentControl in the right of Window, and set Content binding Items (it's type is 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.
像这样:
问题是当我在items中添加一个item时,ContentControl没有更新和改变DataTemplate,我尝试设置mode、UpdateSourceTrigger等,但是失败了.在 ViewModel 中,删除项目后,我使用此语句,它会运行良好<1>:
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. In ViewModel, after delete a item, I use this statements, it will work well <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);
但我想知道为什么它与 <1> 配合得很好.
but I wonder why it work well with <1>.
已编辑 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
将只监听 PropertyChanged
事件,而不监听 CollectionChanged
事件.您需要使用 ItemsControl
或其任何其他版本(如 ListView
)来实现此行为.
ContentControl
will listen only for PropertyChanged
events and not for CollectionChanged
event. You'll need to use either an ItemsControl
or any of its other versions like ListView
for this behavior.
作为一种解决方法,您可以为 ContentControl
创建一个 Style
并定义一个 DataTrigger
而不是 TemplateSelector
> 在 Items.Count
上并相应地设置 ContentTemplate
.类似的东西,
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.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>
这篇关于ContentControl.ContentTemplateSelector 动态选择模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!