首页 > 投稿

WPF 保姆级教程怎么实现一个树形菜单

投稿 会员昵称:印修 关注 投稿量: 粉丝量: 关注量:   2024-09-06 20:47:00A+A-

先看一下效果吧:

WPF 保姆级教程怎么实现一个树形菜单(图1)    

我们直接通过改造一下原版的TreeView来实现上面这个效果

我们先创建一个普通的TreeView

代码很简单:

WPF 保姆级教程怎么实现一个树形菜单(图2)
        <TreeView>
            <TreeViewItem Header="人事部"/>
            <TreeViewItem Header="技术部">
                <TreeViewItem Header="技术部-1"/>
                <TreeViewItem Header="技术部-1"/>
            </TreeViewItem>
            <TreeViewItem Header="财务部"/>
        </TreeView>
WPF 保姆级教程怎么实现一个树形菜单(图2)

实现的效果如下:

WPF 保姆级教程怎么实现一个树形菜单(图4)

如果把这个当成是项目的菜单栏,应该会被领导骂死,一个是不够灵活,数据是写死的;二是样式不好看,只有点文字部分才会展开。

创建一下模板

WPF 保姆级教程怎么实现一个树形菜单(图5)

直接在设计器中右键我们的item,编辑副本,点击确定,我们会得到下面一段代码

WPF 保姆级教程怎么实现一个树形菜单(图6)

里面有一个叫Bd的border,我们把这个border的背景色去掉,然后我们自己去创建两个新的border

WPF 保姆级教程怎么实现一个树形菜单(图2)
<Border Background="Transparent" Margin="-200,0,-200,0" Grid.ColumnSpan="4"/>
<Border x:Name="bd1" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" 
        Margin="-200,0,-200,0" Visibility="Hidden" Grid.ColumnSpan="4">
    <Border.Effect>
        <DropShadowEffect BlurRadius="5" ShadowDepth="2"/>
    </Border.Effect>
</Border><ToggleButton x:Name="Expander" ClickMode="Press" 
              IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
              Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
    <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
WPF 保姆级教程怎么实现一个树形菜单(图2)

上面红色部分是我们新增的两个border,原本的叫Bd的border,我们只保留紫色部分的属性.

原本的代码里面有两个关于Bd的trigger

WPF 保姆级教程怎么实现一个树形菜单(图9)

我们取名为bd1的border,最开始的Visibility设置的是Hidden,我们替换一下关于Bd的trigger,让它变成当IsSelected是true的情况下,让bd1的Visibility变成Visible.

WPF 保姆级教程怎么实现一个树形菜单(图2)
<Trigger Property="IsSelected" Value="true">    <Setter Property="Visibility" TargetName="bd1" Value="Visible"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsSelected" Value="true"/>
        <Condition Property="IsSelectionActive" Value="false"/>
    </MultiTrigger.Conditions>    <Setter Property="Visibility" TargetName="bd1" Value="Visible"/>
    <Setter Property="Background" TargetName="bd1" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
WPF 保姆级教程怎么实现一个树形菜单(图2)

再运行一下,看一下效果

WPF 保姆级教程怎么实现一个树形菜单(图12)

基本上已经算是成功一半了,但是这个时候,我们的菜单只有一个有效果,其他的还是原来的样式,那是因为我们只有一个TreeViewItem使用了我们写的效果

WPF 保姆级教程怎么实现一个树形菜单(图13)

如果我们每一个TreeViewItem都复制一下这句Style="{DynamicResource TreeViewItemStyle1}" ,是不是显得很呆,而且这只是在我们的菜单很少的情况下,如果菜单很多,这个方法就不可行。

所以这里我们用一个TreeView的ItemContainerStyle来操作一下

        <Style x:Key="treeViewStyle1" TargetType="{x:Type TreeView}" BasedOn="{StaticResource {x:Type TreeView}}">
            <Setter Property="ItemContainerStyle" Value="{StaticResource TreeViewItemStyle1}"/>
        </Style>

我们创建一个类型是TreeView的style,把它的ItemContainerStyle设置成我们之前添加的那个style,然后我们把这个style放到我们的TreeView上

WPF 保姆级教程怎么实现一个树形菜单(图14)

这个时候我们再运行就会发现首级菜单的样式都实现我们想要的效果了,但是子集菜单还是原来的样式

我们在代码里面添加下面一个方法

WPF 保姆级教程怎么实现一个树形菜单(图2)
        private void ApplyItemContainerStyle(ItemsControl itemsControl)
        {            foreach (var item in itemsControl.Items)
            {                var treeViewItem = item as TreeViewItem;                if (treeViewItem != null)
                {
                    treeViewItem.Style = treeview1.ItemContainerStyle;
                    ApplyItemContainerStyle(treeViewItem);
                }
            }
        }
WPF 保姆级教程怎么实现一个树形菜单(图2)

然后我们在构造函数里面把我们的TreeView当做是参数传进去

这个方法就是把所有的item和item的子项都设置成treeview的ItemContainerStyle;

WPF 保姆级教程怎么实现一个树形菜单(图17)

我们再启动一下项目,就会发现效果是我们想要的效果了

到这里其实大部分效果都实现了,基本上也可以向领导交差了;

但是还缺少一个数据可拓展性和一个图标的功能,我们先看一下数据可拓展性

在平时的项目里面,一般都会有很多个不同的项目,每个项目可能都有好多个菜单,有的项目还想隐藏某一些菜单,我们总不能所有项目都通过visible属性来设置吧

特别是报表功能可能会有几十个,所以我们需要用到一个东西叫数据模板:HierarchicalDataTemplate;

我们先创建一个类

    public class TreeViewModel
    {        public string Header { get; set; }        public ObservableCollection<TreeViewModel> Children { get; set; }
    }

然后回到设计器里面,把我们的代码改成下面的代码

WPF 保姆级教程怎么实现一个树形菜单(图2)
<TreeView Style="{DynamicResource treeViewStyle1}" x:Name="treeview1">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:TreeViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Height="40" Orientation="Horizontal">
                <TextBlock Text="{Binding Header}" VerticalAlignment="Center"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
WPF 保姆级教程怎么实现一个树形菜单(图2)

对比一下红色部分的绑定,和类的属性,就能知道这个数据模板怎么用了.

再到构造函数里面去添加数据

WPF 保姆级教程怎么实现一个树形菜单(图2)
public ObservableCollection<TreeViewModel> MenuCollection { get; set; }public MainWindow()
{
    InitializeComponent();    MenuCollection = new ObservableCollection<TreeViewModel>()
    {
        new TreeViewModel
        {
            Header = "人事部"
        },
        new TreeViewModel
        {
            Header = "技术部",
            Children = new ObservableCollection<TreeViewModel>
            {
                new TreeViewModel { Header = "技术部-1"},
                new TreeViewModel { Header = "技术部-2"},
            }
        },
        new TreeViewModel
        {
            Header = "财务部",
        },
    };

    treeview1.ItemsSource = MenuCollection;}
WPF 保姆级教程怎么实现一个树形菜单(图2)

注意这两段标红的代码,我们用一个集合MenuCollection模拟一下我们从数据库或者其他地方查询出来的菜单集合,然后把它做为数据源给treeview就可以了

再运行一下项目,它就差不多实现我们想要的效果了,现在再去找领导交差,领导还会夸你做的不错,只是还差一个图标了,这个就是锦上添花的东西了.

我们百度搜索一下  阿里ICON,去到官网里面,创建一个自己的账号,然后搜索一些自己喜欢的图标

WPF 保姆级教程怎么实现一个树形菜单(图22)

 把自己喜欢的图标添加到自己的项目中去,这里的项目名很重要,我取的是  FatSheep

WPF 保姆级教程怎么实现一个树形菜单(图23)

WPF 保姆级教程怎么实现一个树形菜单(图24)

WPF 保姆级教程怎么实现一个树形菜单(图25)

 在到我的项目里面去把这个资源文件下载到自己的项目中

WPF 保姆级教程怎么实现一个树形菜单(图26)

 下载下来的文件,我们把ttf后缀的文件添加到我们的项目里面去

WPF 保姆级教程怎么实现一个树形菜单(图27)

把它作为资源引入到代码里面

WPF 保姆级教程怎么实现一个树形菜单(图28)

<FontFamily x:Key="FatSheep">pack:application:,,,/自己项目的名字;component/Resources/iconfont.ttf#FatSheep</FontFamily>

记得修改一下自己的项目名字,我取的是TreeViewDemo,改成自己的项目名就好了,的结尾,是FatSheep,记得改成自己的ICON项目名称

接着我们在TreeViewModel里面添加一个Icon属性

WPF 保姆级教程怎么实现一个树形菜单(图2)
    public class TreeViewModel
    {        public string Header { get; set; }        public string Icon { get; set; }        public ObservableCollection<TreeViewModel> Children { get; set; }
    }
WPF 保姆级教程怎么实现一个树形菜单(图2)

然后我们在数据源里面添加一下数据

WPF 保姆级教程怎么实现一个树形菜单(图2)
MenuCollection = new ObservableCollection<TreeViewModel>()
{    new TreeViewModel
    {
        Header = "人事部",        Icon = "\ue71c"
    },    new TreeViewModel
    {
        Header = "技术部",        Icon = "\ue71c",
        Children = new ObservableCollection<TreeViewModel>
        {            new TreeViewModel { Header = "技术部-1", Icon="\ue71c"},            new TreeViewModel { Header = "技术部-2" , Icon="\ue71c"},
        }
    },    new TreeViewModel
    {
        Header = "财务部",        Icon = "\ue71c"
    },
};
WPF 保姆级教程怎么实现一个树形菜单(图2)

设计器里面添加一下显示部分的代码

WPF 保姆级教程怎么实现一个树形菜单(图2)
<TreeView Style="{StaticResource treeViewStyle1}" x:Name="treeView1" BorderThickness="0,0,1,0" Grid.Column="1">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:TreeViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Height="40" Orientation="Horizontal">                <TextBlock Text="{Binding Icon}" VerticalAlignment="Center" FontFamily="{StaticResource FatSheep}" Margin="0,0,5,0"/>
                <TextBlock Text="{Binding Header}" VerticalAlignment="Center"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
WPF 保姆级教程怎么实现一个树形菜单(图2)

再启动项目,功能就完成了

WPF 保姆级教程怎么实现一个树形菜单(图35)

这个笑脸是怎么来的了

那是因为我自己的项目里面添加了一个笑脸

WPF 保姆级教程怎么实现一个树形菜单(图36)

我们复制一下这个代码,   &#xe71c;  我们把它改成 \ue71c,这是一个转义字符,就这样我们就能添加如何自己喜欢的图标了。


部分内容需要登录查看

本次有 徐州鑫坤机电设备有限公司 网站:www.xzxkjd.com 展现 转载分享注明本文地址!有疑问,请联系我们:xzxkjd@qq.com 谢谢!

点击这里复制本文地址 以上内容由用户上传和网络在 徐州鑫坤机电设备有限公司 整理呈现,如有侵权请联系站长:xzxkjd@qq.com !

相关内容

加载中~

Copyright © 2012-2024 徐州鑫坤机电设备有限公司 版权所有
苏ICP备2023032739号-1 苏ICP备2023032739号-2 苏公网安备32038202000884
开发中 | 关键词 | 网站地图 | 网站地图 | 网站地图 | TAG集合

今日IP人数 0 今日浏览量(PV) 0 昨日IP人数 0 昨日浏览量(PV) 0 30天浏览量(PV) 0 总访浏览量(PV) 0

网站已运行:

在线客服
服务热线

服务热线

0516-86596070

联系邮箱

服务热线

xzxkjd.@qq.com

微信咨询
我的网站名称
交流群
我的网站名称
返回顶部
X我的网站名称

截屏,微信识别二维码

微信号:xkyinxiu

(点击微信号复制,添加好友)

  打开微信

微信号已复制,请打开微信添加咨询详情!