【愚公系列】2023年10月 WPF控件专题 TreeView控件详解

举报
愚公搬代码 发表于 2023/09/30 23:51:07 2023/09/30
【摘要】 WPF控件是Windows Presentation Foundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

WPF控件是Windows Presentation Foundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。

原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见的标准用户界面元素。

自定义控件则允许开发人员使用XAML和C#等编程语言来创建个性化的用户界面元素。自定义控件可以根据需求提供更多的功能和自定义化选项,以及更好的用户体验。

🚀一、TreeView控件详解

WPF中的TreeView控件是用于显示分层数据结构的控件,通常用于展示树形结构。它具有以下特点:

  1. 支持多层级节点;
  2. 节点可以被折叠或展开;
  3. 可以为节点添加图标;
  4. 节点可以包含任何WPF元素。

TreeView控件的基本用法如下:

  1. 在XAML中添加TreeView控件:
<TreeView Name="treeView">
</TreeView>
  1. 添加根节点和子节点:
<TreeView Name="treeView">
    <TreeViewItem Header="Root">
        <TreeViewItem Header="Child 1"></TreeViewItem>
        <TreeViewItem Header="Child 2"></TreeViewItem>
    </TreeViewItem>
</TreeView>
  1. 为节点添加图标:
<TreeView Name="treeView">
    <TreeViewItem Header="Root">
        <TreeViewItem Header="Child 1" 
        HeaderTemplate="{StaticResource ItemTemplate}">
        </TreeViewItem>
        <TreeViewItem Header="Child 2"
        HeaderTemplate="{StaticResource ItemTemplate}">
        </TreeViewItem>
    </TreeViewItem>
</TreeView>

<DataTemplate x:Key="ItemTemplate">
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding Icon}" />
        <TextBlock Text="{Binding Name}" />
    </StackPanel>
</DataTemplate>
  1. 监听节点被选中事件:
<TreeView Name="treeView" SelectedItemChanged="TreeView_SelectedItemChanged">
    ...
</TreeView>

private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    // 获取选中节点
    var selectedItem = treeView.SelectedItem as TreeViewItem;
    ...
}

🔎1.属性介绍

WPF中TreeView控件的常用属性如下:

  1. ItemsSource:用于指定TreeView的数据源。

  2. ItemTemplate:用于指定TreeView每个节点的展示方式,通常使用DataTemplate来定义。

  3. SelectedItem:表示当前选中的节点。

  4. IsExpanded:表示当前节点是否展开。

  5. IsSelected:表示当前节点是否选中。

  6. ItemContainerStyle:用于指定TreeView的每个节点的样式。

  7. ItemContainerStyleSelector:用于根据节点数据选择不同的样式。

  8. VirtualizingStackPanel.IsVirtualizing:表示是否启用虚拟化来优化TreeView的性能。

  9. VirtualizingStackPanel.VirtualizationMode:表示虚拟化的模式,有Standard、Recycling和None三种模式可选。

🔎2.常用场景

WPF中TreeView控件常用场景有:

  1. 文件和文件夹结构展示——TreeView控件可以很好的展示文件和文件夹的层级结构,这对于文件管理和文档管理应用程序非常有用。

  2. 导航菜单——TreeView控件可以作为导航菜单的一种实现方式,通过展示树形菜单结构来帮助用户快速找到需要的功能模块。

  3. 组织架构图——TreeView控件可以展示组织架构图,比如公司的部门、职位等层级关系。

  4. 菜单下拉列表——TreeView控件可以作为菜单下拉列表的一种实现方式,用户可以通过点击树节点来选择不同的选项。

  5. 多层级分类展示——TreeView控件可以用来展示多层级分类,比如商品分类、新闻分类等。用户可以通过点击树节点来查看对应的子分类或者文章详情。

TreeView控件非常适合展示层级结构数据,对于需要展示层级关系的应用程序来说是必不可少的控件之一。

🔎.具体案例

🦋3.1 静态使用

<Window x:Class="WpfAppTest.TreeViewWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAppTest"
        mc:Ignorable="d"
        Title="TreeViewWindow" Height="450" Width="800">
        <Window.Resources>
                <Style  TargetType="TreeViewItem">
                        <Setter Property="Foreground" Value="Orange"/>
                        <Setter Property="FontSize" Value="14"/>
                        <Setter Property="Padding" Value="10"/>
                        <Setter Property="Background" Value="Transparent"/>
                      
                </Style>
        </Window.Resources>
        <Grid>
                <TreeView Name="tvLsit" HorizontalAlignment="Left" Height="292" Margin="31,25,0,0" VerticalAlignment="Top" Width="330"  SelectedItemChanged="TvLsit_SelectedItemChanged">
                      
                        <TreeViewItem Header="学生管理系统" IsExpanded="True" >
                                <TreeViewItem Header="系统管理" IsExpanded="True">
                                        <TreeViewItem Header="角色管理" IsSelected="True" Foreground="LightBlue"  />
                                        <TreeViewItem Header="用户管理"/>
                                        <TreeViewItem Header="菜单管理"/>
                                        <TreeViewItem Header="权限管理"/>
                                </TreeViewItem>
                                <TreeViewItem Header="业务管理" IsExpanded="False">
                                        <TreeViewItem Header="采购入库"/>
                                        <TreeViewItem Header="销售出库"/>
                                </TreeViewItem>
                        </TreeViewItem>
                </TreeView>

        </Grid>
</Window>

/// <summary>
/// 节点选择响应事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TvLsit_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
        var val = e.NewValue as TreeViewItem;
        MessageBox.Show(val.Header.ToString());
}

🦋3.2 动态使用

<Window x:Class="WpfAppTest.TreeViewWindow2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAppTest"
                xmlns:model="clr-namespace:WpfAppTest.Models"
        mc:Ignorable="d"
        Title="TreeViewWindow2" Height="450" Width="800" Loaded="Window_Loaded">
        <Grid>
                <TreeView Name="tvList" HorizontalAlignment="Left" Height="210" Margin="55,78,0,0" VerticalAlignment="Top" Width="283" ItemsSource="{Binding MenuList}" SelectedItemChanged="TvList_SelectedItemChanged">
                        <TreeView.ItemTemplate>
                                <HierarchicalDataTemplate DataType="{x:Type model:MenuItemModel}" ItemsSource="{Binding SubItems}">
                                        <TextBlock Text="{Binding MenuName}" VerticalAlignment="Center" />
                                </HierarchicalDataTemplate>
                        </TreeView.ItemTemplate>
                </TreeView>

        </Grid>
</Window>

namespace WpfAppTest
{
        /// <summary>
        /// TreeViewWindow2.xaml 的交互逻辑
        /// </summary>
        public partial class TreeViewWindow2 : Window
        {
                public TreeViewWindow2()
                {
                        InitializeComponent();
                }

                private void Window_Loaded(object sender, RoutedEventArgs e)
                {
                        //代码添加节点---并不比xaml代码简洁
                        {
                                //TreeViewItem ti = new TreeViewItem();
                                //ti.Header = "进销存管理系统";
                                //tvList.Items.Add(ti);

                                ////根节点下添加三个子节点
                                //TreeViewItem ti1 = new TreeViewItem();
                                //ti1.Header = "系统管理";
                                //ti.Items.Add(ti1);
                                //TreeViewItem ti2 = new TreeViewItem();
                                //ti2.Header = "业务管理";
                                //ti.Items.Add(ti2);
                                //TreeViewItem ti3 = new TreeViewItem();
                                //ti3.Header = "查询中心";
                                //ti.Items.Add(ti3);

                                ////系统管理节点下添加4个子节点
                                //TreeViewItem ti11 = new TreeViewItem();
                                //ti11.Header = "用户管理";
                                //ti1.Items.Add(ti11);
                                //TreeViewItem ti12 = new TreeViewItem();
                                //ti12.Header = "角色管理";
                                //ti1.Items.Add(ti12);
                                //TreeViewItem ti13 = new TreeViewItem();
                                //ti13.Header = "菜单管理";
                                //ti1.Items.Add(ti13);
                                //TreeViewItem ti14 = new TreeViewItem();
                                //ti14.Header = "权限管理";
                                //ti1.Items.Add(ti14);
                        }

                        {
                                List<MenuInfo> allMenus = GetMenuList();//基础菜单数据
                                List<MenuItemModel> menuList = new List<MenuItemModel>();//目标菜单数据
                                AddAllMenus(allMenus, menuList, null, 0);
                                VMenuModel vmodel = new VMenuModel();
                                vmodel.MenuList = menuList;
                                this.DataContext = vmodel;//当前Window的数据上下文
                        }
           
                }


                /// <summary>
                /// 递归加载菜单项数据
                /// </summary>
                /// <param name="allMenus"></param>
                /// <param name="menusList"></param>
                /// <param name="pMenu"></param>
                /// <param name="parentId"></param>
                private void AddAllMenus(List<MenuInfo> allMenus, List<MenuItemModel> menusList, MenuItemModel pMenu, int parentId)
                {
                        var subList = allMenus.Where(m => m.ParentId == parentId);
                        foreach (var mi in subList)
                        {
                                MenuItemModel miInfo = new MenuItemModel();
                                miInfo.MenuId = mi.MenuId;
                                miInfo.MenuName = mi.MenuName;
                                if (pMenu != null)
                                        pMenu.SubItems.Add(miInfo);
                                else
                                        menusList.Add(miInfo);
                                AddAllMenus(allMenus, menusList, miInfo, mi.MenuId);
                        }
                }

                /// <summary>
                /// 获取菜单数据
                /// </summary>
                /// <returns></returns>
                private List<MenuInfo> GetMenuList()
                {
                        string sql = "select MenuId,MenuName,ParentId from MenuInfos";
                        SqlDataReader dr = SqlHelper.ExecuteReader(sql, 1);
                        List<MenuInfo> list = new List<MenuInfo>();
                        while (dr.Read())
                        {
                                MenuInfo menu = new MenuInfo();
                                menu.MenuId = (int)dr["MenuId"];
                                menu.MenuName = dr["MenuName"].ToString();
                                menu.ParentId = (int)dr["ParentId"];
                                list.Add(menu);
                        }
                        dr.Close();
                        return list;
                }

                private void TvList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
                {
                        //响应操作
                        var val = e.NewValue as MenuItemModel;//
                        MessageBox.Show(val.MenuName);
                }
        }
}
public class VMenuModel
{
        /// <summary>
        /// Menu控件的数据源属性
        /// </summary>
        public List<MenuItemModel> MenuList { get; set; }
}

public class MenuInfo
{
    public int MenuId { get; set; }
    public string MenuName { get; set; }
    public int ParentId { get; set; }
    public string MKey { get; set; }
}

🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。