我有一个xaml页面,上面有ItemsControl控件。 ItemsControl绑定到ObservableCollection的Guests。来宾集合可以包含两种不同类型的对象:USGuest和UKGuest,两者都继承自Guest。是否可以为ItemsControl制作两个(或更多)模板,并根据集合中当前项的运行时类型自动选择它们?
答案 0 :(得分:7)
我没有试过这个,但您是否尝试将ItemsSource设置为Guest对象的ObservableCollection并为这两种类型设置DataTemplate?
<DataTemplate DataType="{x:Type my:USGuestViewModel}">
<my:USGuestView/>
</DataTemplate>
<DataTemplate DataType="{x:Type my:UKGuestViewModel}">
<my:UKGuestView/>
</DataTemplate>
编辑:'my'是ViewModel和Views所在的命名空间的声明,所以你应该在xaml的开头添加这样的东西:
<UserControl x:Class="my.namespace.SuperView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:my.namespace">
我已经检查过,你不能在ItemTemplate属性中设置两个DataTemplates。但您可以在UserControl Resources Property中设置它们:
<UserControl.Resources>
<DataTemplate DataType="{x:Type my:USGuestViewModel}">
<my:USGuestView/>
</DataTemplate>
<DataTemplate DataType="{x:Type my:UKGuestViewModel}">
<my:UKGuestView/>
</DataTemplate>
</UserControl.Resources>
答案 1 :(得分:2)
对不起,我不是故意成为派对的人,也不提供解决方案。但这是我在Silverlight中使用MVVM时遇到的最大障碍之一。
我过去做过的一件事就是使用一个UserControl,里面只有一个ContentPresenter作为ItemsTemplate。 (这么多层!)在UserControl中,当DataContext发生变化时,我会选择一个模板来使用UserControl的资源。 (模板实际上不必在UserControl中,但我最喜欢封装。)
<强>的MainPage 强>:
<UserControl>
<UserControl.Resources>
<DataTemplate x:key="itemTemplate">
<my:ItemView />
</DataTemplate>
</UserControl.Resources>
<ItemsControl ItemTemplate="{StaticResource itemTemplate}" />
</UserControl>
<强> ItemView.xaml:强>
<UserControl>
<UserControl.Resources>
<DataTemplate x:Key="Template1">
<!-- Template #1 -->
</DataTemplate>
<DataTemplate x:Key="Template2">
<!-- Template #2 -->
</DataTemplate>
</UserControl.Resources>
<ContentPresenter Name="presenter"
Content="{Binding}" />
</UserControl>
<强> ItemView.xaml.cs 强>
...
OnDataContextChanged(...)
{
var content = this.DataContext as MyDataType;
DataTemplate template;
switch (content.State)
{
case State1:
template = this.Resources["template1"] as DataTemplate;
break;
case State2:
template = this.Resources["template2"] as DataTemplate;
break;
}
this.presenter.ContentTemplate = template;
}
...
如果您仍在继续,请注意Silverlight也不提供像WPF中那样的OnDataContextChanged方法。因此,要了解这一点,请参阅Jeremy Likness在此处所说的内容:
http://www.codeproject.com/Articles/38559/Silverlight-DataContext-Changed-Event.aspx
我经常使用它。谢谢,杰里米!
此外,与WPF在该领域提供的所有功能相比,这也存在一些非常严重的限制。例如,伪造一个ItemContainerStyle选择器确实没有好办法。 (我知道。)