WPF疑难问题之Treeview中HierarchicalDataTemplate多级样式

2023-10-27

一、问题场景

日常为 TreeView 自定义样式过程中,如果涉及到树形多级样式不同时,又该如何去做?例如树形显示文件夹和文件节点。

TreeView 样式如下:

<HierarchicalDataTemplate x:Key="Folder" 
                          DataType="{x:Type local:TreeItemViewModel}" 
                          ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="/"/>
        <TextBlock Text="{Binding TreeType}"/>
    </StackPanel>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate x:Key="Node" 
                          DataType="{x:Type local:TreeItemViewModel}"
                          ItemsSource="{Binding Children}">
    <TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>

<TreeView ItemTemplate="{DynamicResource Folder}" 
          x:Name="treeview" 
          Width="200" 
          DataContext="{StaticResource TreeViewModel}"
          local:TreeViewAttach.SelectItem="{Binding SeletedItem,Mode=TwoWay}" 
          local:TreeViewAttach.SelectedMonitored="True" 
          ItemsSource="{Binding Path=TreeItems}"  
          VirtualizingPanel.IsVirtualizing="True" 
          VirtualizingPanel.IsVirtualizingWhenGrouping="True">
</TreeView>

TreeViewModel 内容如下:

  public class TreeViewModel:Prism.Mvvm.BindableBase
    {
        private List<TreeItemViewModel> treeItems;

        public TreeViewModel()
        {
            for (int i = 0; i < 10; i++)
            {
                TreeItemViewModel item = new TreeItemViewModel
                {
                    Name = $"test{i}",
                };
                for (int j = 0; j < 10; j++)
                {
                    TreeItemViewModel item01 = new TreeItemViewModel
                    {
                        Name = $"孩子-{i}",
                    };
                    var child = new TreeItemViewModel { Name = $"c{i}-{j}" };
                    for (int m = 0; m < 10; m++)
                    {
                        var childsub = new TreeItemViewModel { Name = $"{child.Name}-{m}" };
                        child.Children.Add(childsub);
                    }
                    item.Children.Add(item01);
                    item.Children.Add(child);
                }
                TreeItems.Add(item);
            }
        }

        public List<TreeItemViewModel> TreeItems
        {
            get {
                if (treeItems == null)
                {
                    treeItems = new List<TreeItemViewModel>();
                }
                return treeItems;
            }
            set => SetProperty(ref treeItems, value);
        }
}

子项TreeViewItemModel 内容如下:

public class TreeItemViewModel : Prism.Mvvm.BindableBase
    {
        private string name;
        public string Name
        {
            get => name;
            set => SetProperty(ref name, value);
        }

        private List<TreeItemViewModel> children;
        public List<TreeItemViewModel> Children
        {
            get {
                if (children == null)
                {
                    children = new List<TreeItemViewModel>();
                }
                return children;
            }
            set => SetProperty(ref children, value);
        }

        public TreeType TreeType { get {
                if (children != null  && children.Count > 0)
                {
                    return TreeType.Folder;
                }
                return TreeType.Node;
            } }
}

运行效果如下:

image-20220307225503061

可以看到,所有的样式都是使用的 Key="Folder"的样式模板。

二、解决思路

如果希望多个样式都应用到 TreeView 中时,需要考虑是否能够给 HierarchicalDataTemplate 本身添加额外的样式。查看 HierarchicalDataTemplate 内部代码:

public class HierarchicalDataTemplate : DataTemplate
{
        public int AlternationCount{}
    
        public BindingGroup ItemBindingGroup{}
    
        public Style ItemContainerStyle{}
    
        public StyleSelector ItemContainerStyleSelector{}
    
        public BindingBase ItemsSource{}
    
        public string ItemStringFormat{}
    
        public DataTemplate ItemTemplate{}
    
        public DataTemplateSelector ItemTemplateSelector{}
    
        public HierarchicalDataTemplate(){}
    
        public HierarchicalDataTemplate(object dataType){}
}

HierarchicalDataTemplateDataTempate 的派生类,同时,也可以将 HierarchicalDataTemplate 视为一个集合控件,能够 ItemTemplate,也能够添加 ItemTemplateSelector,那么此时就可以尝试,通过为 HierarchicalDataTemplate 添加数据模板选择器,进行 HierarchicalDataTemplate 内容项的样式选择。

选择器TreeDataTemplateSelector内容如下:

    public class TreeDataTemplateSelector: DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            TreeItemViewModel treeItem = item as TreeItemViewModel;
            var fe = container as FrameworkElement;

            if (treeItem.TreeType == TreeType.Folder)
            {
                return fe.FindResource("Folder") as DataTemplate;
            }
            return fe.FindResource("Node") as DataTemplate;
        }
    }

HierarchicalDataTemplate 中使用:

<HierarchicalDataTemplate x:Key="Folder" 
                          ItemTemplateSelector="{StaticResource TreeDataTemplateSelector}"
                          DataType="{x:Type local:TreeItemViewModel}" 
                          ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="/"/>
        <TextBlock Text="{Binding TreeType}"/>
    </StackPanel>
</HierarchicalDataTemplate>

运行效果如下:

image-20220307225244587

以上就是 HierarchicalDataTemplate 多级样式的设置解决办法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF疑难问题之Treeview中HierarchicalDataTemplate多级样式 的相关文章

  • WPF DataGrid - 将 TimeSeries 与 MultiBinding 相结合,丢失更改通知。为什么?

    我有一个具有两个 ObservableCollection 的类 其中 TimeValue 是带有更改通知的自定义日期时间 值配对 通过 INotifyPropertyChanged 我将这些称为 目标 和 实际值 当我将它们绑定到图表时
  • 在 WPF 中以编程方式设置 ComboBox SelectedItem (3.5sp1)

    在安装了 Net Framework 3 5 sp1 的 wpf 应用程序中以编程方式设置 SelectedItem 时 我感到很困惑 我仔细阅读了数百篇文章 主题 但仍然感到困惑 我的xaml
  • WPF Datagrid 组扩展文本 - 如何绑定?

    我正在使用带有组合框的数据网格 该组合框应该更改分组字段 我使用以下 xaml 来定义常规分组模板
  • 在WPF中如何添加菜单项事件?

    在我的 WPF 应用程序中 我添加一个菜单 然后在其下添加几个菜单项 例如 我的菜单项之一是 Main Item 然后我在 Main Item 下添加subItem1 subItem2和subItem3 我想单击 subItem1 并执行某
  • MVVM ViewModel 很多属性

    我是 MVVM 新手 正在开发一个应用程序 我有一个包含很多属性的表单视图 大约 50 个 我不能将它们分离到用户控件中 因为这会破坏 mvvm 原则 我无法将它们分成模型 因为它们包含逻辑 属性更改 错误更改这些都不是 poco 类 并且
  • 当 DataTable 为空时,DataGrid 显示空行

    我有一个DataGrid dg1 绑定到DataTable 数据集 表 代码运行良好并且DataGrid正在显示数据DataTable正确 但是 如果我Clear the DataTable the DataGrid也很清楚 但留下一个空行
  • WPF XAML 定义的 MenuItem 重用开始工作,然后消失

    以下简单代码尝试在两个单独的菜单上重用 Window Resources 中定义的 MenuItem
  • 如何在 WPF 中设置窗口边框和标题栏的样式? [复制]

    这个问题在这里已经有答案了 我们正在开发一个 WPF 应用程序 它使用 Telerik 的控件套件 一切正常且看起来很好 不幸的是 我们最近需要替换所有对话框的基类 将 RadWindow 更改为标准 WPF 窗口 原因与本讨论无关 通过这
  • 尝试了解使用服务打开对话框

    我已经阅读了有关使用 mvvm 模式打开对话框的讨论 我看过几个使用服务的示例 但我不明白所有部分如何组合在一起 我发布这个问题寻求指导 以了解我应该阅读哪些内容 以更好地理解我所缺少的内容 我将在下面发布我所拥有的内容 它确实有效 但从我
  • WPF:在关闭事件触发之前,不会提交对具有焦点的文本框的更改

    我有一个用于编辑数据库信息的 WPF 窗口 它使用实体框架对象表示 当用户关闭窗口时 我想在 Closing 事件中注意到信息是否已更改 并显示一个消息框 提供将更改保存到数据库的信息 不幸的是 在编辑失去焦点之前 对当前焦点编辑的更改不会
  • 使用隧道而不是冒泡的路由命令

    我有一个自定义控件 MyControl 公开自定义命令 我想要家长Window能够调用此命令 以及所有MyControls应该对此做出反应 我已将命令添加到MyControl s CommandBindings集合 它还提供了CanExec
  • 如何在 WPF 中设置覆盖全局样式的特定控制元素设置?

    我通过应用程序范围的资源字典为应用程序中的按钮定义了全局样式 样式如下所示 来自另一个 SO 示例
  • WPF:鼠标按下时不会触发鼠标离开事件

    我遇到鼠标进入 离开事件的问题 当按下鼠标按钮并按住光标在控件内 然后光标以足够快的速度移出控件时 此事件不会触发 你能告诉我为什么会这样吗 有什么方法可以正确获取这些事件吗 请检查示例项目以查看其实际效果 https www dropbo
  • GridSplitter 从右侧调整大小 - 奇怪的行为

    使用 Kaxaml 从左侧调整大小可以按预期工作
  • WPF 本地化扩展 MVVM 绑定

    我正在尝试绑定在 ViewModel 中声明的名为 SampleName 的属性 这里 SampleName 是关键 但是 当尝试下面的代码时 它显示为空
  • 内容更新时自动调整列表视图列的大小

    我试图让列表视图中的 gridviewcolumns 在更新绑定源 视图模型上的可观察集合 时自动调整内容大小 列表视图填充正常 但当我刷新 更新集合时不起作用 这是我到目前为止正在尝试的解决方案 XAML
  • 在表格中可视化 2D 数据

    我需要一些帮助并且需要指出正确的方向 我正在创建一个应显示二维数据的 WPF 应用程序 它应该显示如下 y x 1 2 3 4 5 1 1 2 3 4 5 2 2 4 6 8 10 3 3 6 9 12 15 4 4 8 12 16 20
  • 密码盒和 MVVM

    我们有以下场景 MVVM 用户界面 用户可以在其中输入密码 实际上是一个PasswordBox 应该做一些工作的服务器 服务器连接到一些需要身份验证的数据库 我已经读过这个关于MVVM中PasswordBox的问题 https stacko
  • 如何识别单击的按钮属于哪个列表框项?

    在 WPF 编程中 我在编写按钮单击事件处理程序时遇到问题 因为该按钮位于列表框项目 数据模板的一部分 内 当单击该按钮时 我无法判断它属于哪个项目 有什么解决办法吗 求救 您似乎已将列表框绑定到集合 并且您的按钮是数据模板或项目模板的一部
  • RichTextbox SelectionStart 返回错误的索引

    我需要向用户显示光标上文本的选择开始和长度 就像在 notepad exe 中一样 选择长度没有问题 因为 Richtextbox 支持带有开始和结束的选择属性 http msdn microsoft com en us library s

随机推荐

  • FTP,Telnet,SMTP,DNS,TFTP,WWW,POP采用的是TCP协议还是UDP协议?各自默认的端口号是多少?

    FTP 采用TCP协议 默认端口21 TELNET采用TCP协议 默认端口23 SMTP采用UDP协议 默认端口25 DNS采用UDP协议 默认端口53 TFTP采用UDP协议 默认端口69 WWW采用TCP协议 默认端口80 POP采用T
  • C++函数重载 (初学)

    恶补C 中 看视频学到了函数重载 放一些笔记以备后面回顾 函数重载规则 1 函数名相同 2 参数个数不同 参数的类型不同 参数个数不同 参数顺序不同 均可构成重载 3 返回值类型不同则不可以构成重载 如 int p int a 和 floa
  • 【信息收集】指纹识别

    一 指纹识别介绍 指纹收集是信息收集非常重要的一个环节 通常包括系统 中间件 web程序 防火墙四个方面 比如在web程序指纹中的cms识别可以直接查找已有的漏洞进行利用 其他方面也都有助于下一步的攻击操作 先来几个在线工具 yunsee
  • Vue自定义指令 传递参数

    在项目开发过程中 难免会遇到各种功能需要使用Vue自定义指令 directive 去实现 关于directive的使用方式这里就不做过多的介绍了 Vue官方文档中说的还是听明白的 今天讲讲在使用Vue自定义指令过程中 1 怎么数据传递到自定
  • Idea 设置类和方法的注释(获取参数)

    Idea 添加注释 类注释 方法注释 类注释 方法注释 类注释 File Setting Editor File and Code Templates Class 注释模板 description author fqtang time DA
  • nginx下location的root和alias指令配置总结

    Nginx配置中location root和alias的关系一直很让人困惑 查询好多资料也没能搞明白 于是自己进行了实际操作 总结如下 1 root指令 说明 在location和root上 后面可以带 也可以不带 效果一样 tree da
  • centos7 RPM包之rpm命令

    RPM包与源码包的区别 1 软件包分类 源码包 C源代码包 rpm包 编译之后的二进制包 2 源码包 优点 开源 可以自由选择所需功能 可看源代码 卸载方便 直接删除安装位置 缺点 安装步骤过多 编译时间过长 3 RPM包 优点 使用简单
  • shell 输出7的倍数

    题目链接 题目描述 写一个 bash脚本以输出数字 0 到 500 中 7 的倍数 0 7 14 21 的命令 最 的语言就是shell了 注意点 数学运算用 expr 命令 且 乘法 用 在前面进行转义 变量前得加个 bin bash l
  • GETH的安装和使用(Windows)

    目录 一 Geth介绍 二 Geth安装 1 下载安装 2 配置环境变量 三 Geth私有链搭建 1 创建创世块文件 2 初始化区块链 3 启动私有节点 四 账户交易 1 创建账户 2 挖矿操作 3 查看区块和奖励 4 转账交易 一 Get
  • openGL之API学习(八十)狭义的游戏引擎的定义

    狭义的游戏引擎的定义 wiki 图形渲染 粒子系统 物理系统 骨骼系统 角色系统 动画系统 场景管理 可视剔除 层次细节 界面模块 脚本接口 纹理模型资源管理 音频功能 网络模块 AI模块 视频功能 更新功能 多核支持 外围工具链
  • Cannot find template location: classpath:/templates/(please add some templates or check your Thymel)

    一 异常信息 Cannot find template location classpath templates please add some templates or check your Thymeleaf configuration
  • C++ shared_ptr和std::move

    以shared ptr为参数调用std move并用等于号时 会调用共享指针的移动构造函数 从而使原共享指针失效 include
  • 目标检测——Detectron2的学习笔记

    1 Detectron2的官方地址 https github com facebookresearch detectron2
  • ssh root账号远程连接出现Permission denied错误

    ssh root账号远程连接出现Permission denied错误 网上搜这个问题出来的问题大多都是修改sshd config中的PermitRootLogin yes 但在我修改之后依然无法登陆 搜到了另一个不知道原因的方法 把你要远
  • 李彦宏被《时代》周刊评为全球AI领袖

    北京时间9月7日晚 时代 周刊发布了首届全球百大AI人物 百度创始人 董事长兼首席执行官李彦宏被评为全球AI领袖 时代 肯定了李彦宏对AI的长期投入及百度在AI方面取得的多项成就 李彦宏是中国最杰出的未来主义者 长期投身于AI发展的浪潮 A
  • NLP领域的预训练模型(Transformer、BERT、GPT-2等)

    英文原文链接 https www analyticsvidhya com blog 2019 03 pretrained models get started nlp 1 介 绍 如今 自然语言处理 Natural Language Pro
  • 远景智能笔试

    第一次复习 操作系统只给一个进程一个时间片 不管你内部有多少个线程 我只给你一个 怎么分配是你的事情 第一次做 30 没有听过的题目 50 知道个大概的题目 20 有把握的题目 远景智能笔试题目链接 多线程和多进程 父子进程间遵循读时共享写
  • MySQL5.7与8.0数据库驱动配置区别

    MySQL5 7 spring datasource url jdbc mysql 192 168 31 200 3306 xxl job useUnicode true characterEncoding utf 8 useSSL fal
  • 深度学习Week9-YOLOv5-C3模块实现(Pytorch)

    本文为 365天深度学习训练营 中的学习记录博客 参考文章 Pytorch实战 第P8天 YOLOv5 C3模块实现 训练营内部成员可读 原作者 K同学啊 接辅导 项目定制 了解C3的结构 方便后续YOLOv5算法的学习 采用的数据集是天气
  • WPF疑难问题之Treeview中HierarchicalDataTemplate多级样式

    文章目录 一 问题场景 二 解决思路 一 问题场景 日常为 TreeView 自定义样式过程中 如果涉及到树形多级样式不同时 又该如何去做 例如树形显示文件夹和文件节点 TreeView 样式如下