65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight DataTemplateSelector

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (27投票s)

2010年7月7日

CPOL

2分钟阅读

viewsIcon

119817

downloadIcon

1491

在 Silverlight 中实现 DataTemplateSelector

引言

WPF的一个很酷的功能是能够根据自己的标准将模板应用于数据块。这是通过实现 DataTemplateSelector 类来实现的。在Silverlight中,我们缺少使用 DataTemplateSelector 的能力,因此我们需要使用更多的代码来填补这个空白。

背景

本文的核心思想是通过创建一个 DataTemplateSelector 类来实现这种缺失的功能。

Using the Code

这个概念相当简单,你有一个从 ContentControl 扩展的 abstract 类,它将调用虚拟方法 SelectTemplate。 想法是尽可能地模仿 DataTemplateSelector ,以便我们不会在使用和重用它时遇到问题。

这个 abstract 类很简单

public abstract class DataTemplateSelector : ContentControl
{
    public virtual DataTemplate SelectTemplate(
        object item, DependencyObject container)
    {
        return null;
    }

    protected override void OnContentChanged(
        object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        ContentTemplate = SelectTemplate(newContent, this);
    }
}

然后,为了我们的使用,就像在WPF中一样,我们需要创建一个具有特定 SelectTemplate 重写的类,该类将把 Template 应用于指定的数据块。 这是一个例子

public class CountryTemplateSelector : DataTemplateSelector
{
    public DataTemplate BrazilTemplate
    {
        get;
        set;
    }

    public DataTemplate UsaTemplate
    {
        get;
        set;
    }

    public DataTemplate EnglandTemplate
    {
        get;
        set;
    }

    public override DataTemplate SelectTemplate(
        object item, DependencyObject container)
    {
        City itemAux = item as City;
        if (itemAux != null)
        {
            if (itemAux.Country == "Brazil")
                return BrazilTemplate;
            if (itemAux.Country == "USA")
                return UsaTemplate;
            if (itemAux.Country == "England")
                return EnglandTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

因此,如果 CountryTemplateSelector 的内容是 City,它将根据国家/地区验证返回我们的模板,返回类所需的模板,就像在WPF中一样。 当然,由于文章仅显示概念,我做了一个非常简单的验证,但你可以将任何逻辑添加到你的 SelectTemplate 方法中。

正如我所说,相当简单,就像在WPF中一样。 但在Silverlight中,由于控件中缺少 ItemTemplateSelectorContentTemplateSelector 等属性,当然会存在差异。

这些差异也很小,我们不必使用一个属性来保存对 ResourceDictionary 中表示 DataTemplateSelector StaticResource 的引用,而是必须将类作为 DataTemplate 的内容添加,如下所示

<ListBox ItemsSource="{Binding Cities}" HorizontalContentAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:CountryTemplateSelector Content="{Binding}">
                <local:CountryTemplateSelector.BrazilTemplate>
                    <DataTemplate>
                        <Grid Background="Green">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.BrazilTemplate>
                <local:CountryTemplateSelector.UsaTemplate>
                    <DataTemplate>
                        <Grid Background="Blue">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.UsaTemplate>
                <local:CountryTemplateSelector.EnglandTemplate>
                    <DataTemplate>
                        <Grid Background="Red">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.EnglandTemplate>
            </local:CountryTemplateSelector>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

就这样。 你的控件渲染所需场景所需的模板。

谢谢

这段代码是一种应用非常灵活功能的简单方法。 希望这能帮助你的开发,让你的生活更轻松一些。 不要忘记留下消息表达你的看法,我真的很乐意听取更多意见。

此致。

历史

  • 2010年7月7日:初始发布
© . All rights reserved.