1

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

public abstract class ContentPartViewModel : ViewModel
{
}

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

public class TitleContentPartViewModel : TextContentPartViewModel
{
}

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

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

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

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

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

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

另一种选择是提供一个DataTemplateSelector并进行从视图模型类型到DataTemplate我自己的映射。唉,ItemsControl在 SL2 中没有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的情况是否有所改善?

谢谢,肯特

4

1 回答 1

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);
    }
}
于 2009-07-15T02:37:13.500 回答