Edward_jie

for you, my Hall of Frame

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  92 随笔 :: 45 文章 :: 539 评论 :: 43万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

我们可以通过ItemTemplate设置ListBoxItem的显示模板,但是这样设置的模板有一个缺陷,那就是所有的Item都用同一个模板,所以的Item都千篇一律,有的时候我们是需要一点点变化的。
在wpf中是支持DataTemplateSelector的,它可以根据条件为不同的Item选择不同的模板,于是我们就模拟实现一下DataTemplateSelector的功能。

原理:
ListBoxItem一般用ItemTemplate来定义item的展示方式,于是:
1. 我们自定义一个ContentControl,名CityTemplateSelector,ItemTemplate就显示这个ContentControl
2. 于是我们把Item的内容传给CityTemplateSelector,作为它的Content
3. CityTemplateSelector定义三个DataTemplate,分别为BeijingTemplate,ShanghaiTemplate,OtherCityTemplate
4. CityTemplateSelector这个ContentControl有了Content了,但是还没有设置ContentTemplate,于是我们在其OnContentChanged even中判断Content的内容,然后根据内容选择不同的Template。

实现步骤:
1. 定义DataTemplateSelector,它是一个基类,继承于ContentControl,当ContentControl的Content属性变化时候,选择不同的展示模板,代码如下:

复制代码
   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);
        }
    }
复制代码

2. 定义CityTemplateSelector,继承于DataTemplateSelector
最重要的定义三套模板,并实现SelectTempalte,代码如下:

复制代码
public class CityTemplateSelector : DataTemplateSelector
    {
        public DataTemplate BeijingTemplate
        {
            get;
            set;
        }

        public DataTemplate ShanghaiTemplate
        {
            get;
            set;
        }

        public DataTemplate OtherCityTemplate
        {
            get;
            set;
        }

        public override DataTemplate SelectTemplate(
            object item, DependencyObject container)
        {
            City city = item as City;
            if (city != null)
            {
                if (city.Name == "Beijing")
                    return BeijingTemplate;
                else if (city.Name == "Shanghai")
                    return ShanghaiTemplate;
                else
                    return OtherCityTemplate;
            }

            return base.SelectTemplate(item, container);
        }
    }
复制代码

3. 使用CityTemplateSelector,代码如下:

复制代码
            <ListBox HorizontalAlignment="Stretch" x:Name="listBox1">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <local:CityTemplateSelector Content="{Binding}">
                            <local:CityTemplateSelector.BeijingTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}" Foreground="Red"/>
                                </DataTemplate>
                            </local:CityTemplateSelector.BeijingTemplate>
                            <local:CityTemplateSelector.ShanghaiTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}" Foreground="Green"/>
                                </DataTemplate>
                            </local:CityTemplateSelector.ShanghaiTemplate>
                            <local:CityTemplateSelector.OtherCityTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}" Foreground="Blue"/>
                                </DataTemplate>
                            </local:CityTemplateSelector.OtherCityTemplate>
                        </local:CityTemplateSelector>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
复制代码

大家可以看到ListBoxItem就是一个CityTemplateSelector,我们为这个CityTemplateSelector的三个模板都赋值了,但是CityTemplateSelector会选择其中一个作为其ContentTemplate。
4. 关于City类就不介绍了,它只有一个Name属性
5. 运行效果如下,其中Beijing和Shanghai显示颜色与其他的item是不同的

 

本文由DEVDIV.com VINCENT(vincent@devdiv.com)原创,转载请注明出处!!!

posted on   Edward_诺  阅读(287)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示