代码之家  ›  专栏  ›  技术社区  ›  Kent Boogaart

在Silverlight 2中呈现视图模型的异构集合

  •  1
  • Kent Boogaart  · 技术社区  · 17 年前

    public abstract class ContentPartViewModel : ViewModel
    {
    }
    
    public class TextContentPartViewModel : ContentPartViewModel
    {
        public string Text { ... }
    }
    
    public class TitleContentPartViewModel : TextContentPartViewModel
    {
    }
    
    public class HyperlinkContentPartViewModel : TextContentPartViewModel
    {
        public string Uri { ... }
    }
    

    我有一个包含一组 ContentPartViewModel 拟提交的文件:

    public class ContentViewModel
    {
        public ICollection<ContentPartViewModel> ContentParts { ... }
    }
    

    然后我有一个 ContentView

    <UserControl ...>
        <ItemsControl ItemsSource="{Binding ContentParts}"/>
    </UserControl>
    

    在理想的世界里,我只会定义一个 DataTemplate 对于每种内容部件类型,将相应地呈现它们。但是,Silverlight不支持 DataType 土地上的财产 数据模板 类,因此这不是一个选项。

    另一个选择是提供 DataTemplateSelector 并将视图模型类型映射到 数据模板 我自己唉,, ItemsControl ItemTemplateSelector 属性-仅是一个 ItemTemplate 所有物

    这让我别无选择,只能提供 然后使用转换器关闭除与该内容部分相关的部分之外的所有UI:

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding Text}" FontWeight="Bold" Visibility="{Binding Converter={StaticResource TitleContentPartConverter}}"/>
    
                <TextBlock Text="{Binding Text}" Visibility="{Binding Converter={StaticResource TextContentPartConverter}}"/>
    
                <HyperlinkButton Content="{Binding Text}" NavigateUri="{Binding Uri}" Visibility="{Binding Converter={StaticResource HyperlinkContentPartConverter}}"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    

    对于性能和代码的可读性/正确性来说,这显然是相当糟糕的。这也使得我更难正确格式化输出。因此,问题是:

    1. 有人能推荐一种更好的方法在SL2中实现这一点吗?
    2. 有人能确认SL3的情况是否有所改善吗?

    肯特

    1 回复  |  直到 17 年前
        1
  •  1
  •   Michael Sync    17 年前
    1. 对Silverlight 2或Silverlight 3不支持DataTemplate中的数据类型。

    2. 您可以在Silverlight中使用ItemTemplateSelector。请看一下这个样品。

    http://silverlight.net/forums/t/12598.aspx

    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item); 
        DataTemplateSelector selector = this.ItemTemplateSelector;
    
        if (null != selector)
        {
            ((ContentPresenter)element).ContentTemplate = selector.SelectTemplate(item, element);
        }
    }