【问题标题】:Rendering a Heterogeneous Collection of View Models in Silverlight 2在 Silverlight 2 中呈现视图模型的异构集合
【发布时间】:2009-07-14 13:13:39
【问题描述】:

我有一个代表格式化内容的视图模型层次结构:

public abstract class ContentPartViewModel : ViewModel
{
}

public class TextContentPartViewModel : ContentPartViewModel
{
    public string Text { ... }
}

public class TitleContentPartViewModel : TextContentPartViewModel
{
}

public class HyperlinkContentPartViewModel : TextContentPartViewModel
{
    public string Uri { ... }
}

我有一个包含要呈现的ContentPartViewModels 集合的包含视图模型:

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

然后我有一个 ContentView 来呈现内容的所有部分:

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

在理想情况下,我只需为每个内容部分类型定义一个DataTemplate,然后相应地呈现它们。但是,Silverlight 不支持 DataTemplate 类上的 DataType 属性,因此这不是一个选项。

另一种选择是提供DataTemplateSelector 并自己进行从视图模型类型到DataTemplate 的映射。唉,SL2 中的 ItemsControl 没有 ItemTemplateSelector 属性 - 只有 ItemTemplate 属性。

这让我别无选择,只能提供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 的情况是否有所改善?

谢谢, 肯特

【问题讨论】:

  • 如果它让你感觉更好,ModelView 中的“视图”实际上解释了绑定中可见性的存在。但是我确实感受到了你的痛苦(并且也在等待 SL5)

标签: collections silverlight-3.0 mvvm silverlight-2.0 heterogeneous


【解决方案1】:
  1. 是的。 Silverlight 2 或 Silverlight 3 不支持 DataTemplate 中的 DataType。

  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);
    }
}

【讨论】:

  • 谢谢迈克尔。我必须自己创建所有基础设施并将各种 ItemsControl 子类化,这并不理想,但似乎它应该可以工作。试了会更新。
  • 没有这个链接的示例和这个问题也并不完整:forums.silverlight.net/forums/t/79266.aspx 这向您展示了如何定义 DataTemplate 资源并以编程方式引用它们。
猜你喜欢
  • 2010-10-24
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2015-01-31
相关资源
最近更新 更多