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 - 在样式中使用 ControlTemplate 资源

    创建样式时 是否可以将 ControlTemplate 属性设置为先前定义的资源 例如 如果我在 ResourceDictionary 中有以下内容
  • 如何从页面级别获取父框架?

    我有一个带有框架和几页的窗口 加载窗口时 框架导航到欢迎页面 当我单击欢迎页面内的按钮时 我希望父框架导航到另一个页面 为此 我需要从页面级别访问父框架 但我不知道如何执行此操作 我尝试了下面的代码 但它返回 null private vo
  • TargetType="controlType" 和 TargetType="{x:Type controlType}" 之间的区别

    在 WPF 中 您可以设置TargetType类型的名称 或者您可以将其设置为 x Type nameOfType 有谁知道有什么区别 没有什么 由于属性类型是Type XAML 解析器知道尝试将您提供的任何内容转换为Type 在其他情况下
  • 如何在 WPF 中实现虚线或点线边框?

    我有一个ListViewItem我正在申请Style到 我想把灰色虚线作为底部Border 我怎样才能在 WPF 中做到这一点 我只能看到纯色画笔 这在我们的应用程序中效果很好 允许我们使用真正的边框而不是乱用矩形
  • 我可以禁用特定控件的键盘输入吗?

    是否可以禁用控件的键盘输入 例如一个ListView 我怎么做 我尝试过覆盖KeyUp KeyDown事件 但显然不是这样的 IsEnabled是一个很好的解决方案 但是我只想禁用键盘交互并保持鼠标交互不变 处理KeyDown事件来得太晚了
  • 获取代码中的绑定结果

    我可能正在以错误的方式寻找这个 但是 有没有办法通过代码获取绑定的结果值 可能是一些显而易见的东西 但我就是找不到它 您只需致电ProvideValue的绑定方法 困难的部分是你需要通过有效的IServiceProvider到方法 编辑 实
  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • 无法使用 DialogResult

    我尝试使用DialogResult检查一个Messagebox s 是 否 取消 我正在使用以下代码 我没有看到任何问题 DialogResult dlgResult MessageBox Show Save changes before
  • 更改鼠标悬停时的矩形背景

    所以我有一个没有背景的矩形 当用户将鼠标悬停在其上时 我想给它一个背景渐变 然后当鼠标离开矩形时删除渐变 请有人发布所需的代码 并告诉我将其放在 cs xaml 文件中的位置吗 Thanks This
  • 窗口关闭后仍在调用方法

    首先我不知道这是不是一个愚蠢的问题 我有这样的场景 首先我有一个主窗口 public MainWindow InitializeComponent dt is a System Windows Threading DispatcherTim
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • ListView ItemContainerStyle 模板

    我创建了用作 ListView 项目模板的样式 其中包含 CheckBox 和 TextBlock
  • 如何在运行时添加到 TreeView 目录

    我有一个TreeView我想允许用户添加和删除子项目 在探索基本功能时 我使用button and a textbox添加此子项 当用户点击button a new TreeViewItem需要创建并设置为我的父项的子项TreeView与t
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 如何在 WPF 应用程序上执行异步启动?

    我在异步等待方面相当落后 所以这可能是一个 duh 问题 我正在开发一个非常小的 UI 应用程序 它使用以下命令从系统托盘运行WPF 通知图标 http www codeproject com Articles 36468 WPF Noti
  • 从一张图像复制 ROI 并复制到 wpf 中的另一张图像

    我想开发一个具有以下签名的函数 CopyImage ImageSource inputImage Point inTopLeft Point InBottomRight ImageSource outputImage Point outTo
  • Visual Studio 扩展找不到所需的程序集

    我为 Visual Studio 2013 编写了一个扩展 因为该死的组合框错误 https stackoverflow com questions 7800032 cancel combobox selection in wpf with

随机推荐

  • 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 样式如下