2010-06-28 73 views
1

我有一个xaml页面,它上面有一个ItemsControl控件。 ItemsControl绑定到ObservableCollection的Guests。客人收藏品可以具有两种不同类型的物品:USGuest和UKGuest,均从客人继承。是否有可能为ItemsControl制作两个(或更多)模板,并根据集合中当前项目的运行时类型自动选择它们?如何使ItemsControl根据运行时类型选择不同的模板

+0

等一下,你问的是在Silverlight中这样做的,对吧? – MojoFilter 2010-07-06 14:26:16

回答

2

对不起,我不是故意要扫大家的兴,而不是提供一个解决方案。但这是我在Silverlight中使用MVVM时遇到的最大障碍之一。

我在过去做过的一件事就是使用一个带有ContentPresenter的UserControl作为ItemsTemplate。 (如此多的图层!)在UserControl中,当DataContext发生变化时,我会从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方法。因此,要覆盖,看看有什么杰里米Likness在这里说一下:

http://www.codeproject.com/Articles/38559/Silverlight-DataContext-Changed-Event.aspx

我用那个漂亮频繁。谢谢,杰里米!

此外,与WPF在该领域为您提供的所有功能相比,还存在一些非常严格的限制。例如,真的没有什么好办法伪造一个ItemContainerStyle选择器。 (我知道的。)

7

我还没有尝试过这个,但是您是否尝试将ItemsSource设置为Guest对象的ObservableCollection并为这两种类型设置DataTemplate?

<DataTemplate DataType="{x:Type my:USGuestViewModel}"> 
    <my:USGuestView/> 
</DataTemplate> 
<DataTemplate DataType="{x:Type my:UKGuestViewModel}"> 
    <my:UKGuestView/> 
</DataTemplate> 

编辑:“我”是你的ViewModels和视图生活的命名空间的声明,所以你应该在XAML的beggining添加如下内容:

<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> 
    <DataTemplate DataType="{x:Type my:USGuestViewModel}"> 
     <my:USGuestView/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type my:UKGuestViewModel}"> 
     <my:UKGuestView/> 
    </DataTemplate> 
</UserControl.Resources> 
+1

+1,这可能是最好的方式。只需将这些模板放置在ItemsControl的资源中 – 2010-06-28 14:07:06

+0

我在ItemControl的资源中添加了模板,并且出现构建错误“成员”DataType“无法识别或访问”。我提到我正在开发Silverlight 4项目吗?这一切都可以在Silverlight中实现吗? – durad 2010-06-28 14:19:35

+0

我认为它虽然有一些方法不存在于Silverlight中。我不认为是这样。我将使用更完整的代码编辑帖子代码片段 – jpsstavares 2010-06-28 15:05:43

相关问题