WPF+MVVM案例实战(十五)- 实现一个下拉式菜单(上)

文章目录

  • 1 案例效果
  • 2、图标资源下载
  • 3、功能实现
    • 1.文件创建
    • 2、菜单原理分析
    • 3、一级菜单两种样式实现
      • 1、一级菜单无子项样式实现
      • 2、一级菜单有子项样式实现
  • 4、总结


1 案例效果

`提示在这里插入图片描述

2、图标资源下载

从阿里矢量素材官网下载需要的菜单图片,如下所示:
在这里插入图片描述

3、功能实现

1.文件创建

打开 Wpf_Examples 项目,在Views 文件夹下创建 窗体 DropDownMenuWindow.xaml 文件。这里我们拆解一下菜单结构,如下图所示

在这里插入图片描述
在WPF中菜单控件为 Menu 菜单项为 MenuItem。如果仅从菜单结构描述,那么如下所示即可实现三级结构。
在这里插入图片描述

 <MenuItem Header="一级菜单" Width="80" Height="30"><MenuItem Header="二级菜单名1" Width="80" Height="30"><MenuItem Header="三级菜单" Width="80" Height="30"></MenuItem></MenuItem><MenuItem Header="二级菜单名2" Width="80" Height="30"></MenuItem><MenuItem Header="二级菜单名3" Width="80" Height="30"></MenuItem></MenuItem>

这就是三级菜单的框架了,我们要做的其实就是美化样式和点击效果了。

2、菜单原理分析

看了上面,我们明白了菜单就是 MenuItem 的嵌套,每一层就是 MenuItem 的样式实现,那么这个样式有规律吗,答案是有的。首先观察一级菜单,发现一级菜单的面板是在菜单的正下方出现,而二级菜单是在菜单项的右侧出现。每个菜单分两种情况,有子菜单项和无子菜单项两种情况。到这里我们已经明白了,菜单其实只有四种样式,一级菜单无子项样式、一级菜单有子项样式、二级菜单无子项样式和二级菜单有子项样式。而不管多少级菜单,只要是一级菜单就使用 一级菜单无子项样式或一级菜单有子项样式,二级及以上菜单就使用二级菜单无子项样式和二级菜单有子项样式。明白了以上道理,我们来逐个实现样式。

3、一级菜单两种样式实现

1、一级菜单无子项样式实现

首先样式按照下图分割:
在这里插入图片描述
整个样式 MenuItemStyle 实现如下:

 <Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type MenuItem}"><Border x:Name="border" BorderThickness="0" CornerRadius="5"Background="{TemplateBinding Background}"Height="{TemplateBinding Height}"Width="{TemplateBinding Width}" ><Grid><ContentPresenter ContentSource="Icon" HorizontalAlignment="Left"VerticalAlignment="Center" Height="16"Width="16" Margin="8 0 0 0"/><ContentPresenter ContentSource="Header" HorizontalAlignment="Left"VerticalAlignment="Center" TextBlock.Foreground="{TemplateBinding Foreground}"TextBlock.FontFamily="{TemplateBinding FontFamily}"TextBlock.FontSize="{TemplateBinding FontSize}"Margin="30 0 0 0"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsHighlighted" Value="True"><Setter Property="Background" TargetName="border" Value="#524E4F"/><Setter Property="BorderBrush" TargetName="border" Value="#524E4F"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

结合图示,很容易就能理解每个样式属性的含义,最后加上样式触发效果,IsHighlighted 选中后背景色改变即可。
我们应用样式后效果如下:

 <MenuItem Header="一级菜单" Width="100" Height="30" Style="{StaticResource MenuItemStyle}"><MenuItem.Icon><Image Source="/Assets/Images/bianji.png" /></MenuItem.Icon><MenuItem Header="二级菜单名1" Width="80" Height="30"><MenuItem Header="三级菜单" Width="80" Height="30"></MenuItem></MenuItem><MenuItem Header="二级菜单名2" Width="80" Height="30"></MenuItem><MenuItem Header="二级菜单名3" Width="80" Height="30"></MenuItem></MenuItem>

在这里插入图片描述
是不是有感觉了,由于样式是不带子项的,所以子项菜单在应用无子项菜单样式就没办法看到子项面板了。那么接下来实现有子项菜单的样式。

2、一级菜单有子项样式实现

分析一下有子项的菜单,其实就是在一级菜菜单下方增加一个弹出的面板。然后再弹出的面板上实现样式。粉衣及时不难发现应该和无子项样式差不多,只需要稍微改造一下,增加一个弹出面板。MenuItemStyleDropDown 示意图如下所示:

在这里插入图片描述
按照上述示意图,很容易在一级无子项菜单的样式上改造,改造后的代码如下:

 <Style x:Key="MenuItemStyleDropDown" TargetType="MenuItem"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type MenuItem}"><Border x:Name="border" Background="{TemplateBinding Background}"BorderThickness="0" Height="{TemplateBinding Height}"Width="{TemplateBinding Width}" CornerRadius="5"><Grid><ContentPresenter ContentSource="Icon" HorizontalAlignment="Left"VerticalAlignment="Center" Height="16"Width="16" Margin="8 0 0 0"/><ContentPresenter ContentSource="Header" HorizontalAlignment="Left"VerticalAlignment="Center" TextBlock.Foreground="{TemplateBinding Foreground}"TextBlock.FontFamily="{TemplateBinding FontFamily}"TextBlock.FontSize="{TemplateBinding FontSize}"Margin="30 0 0 0"/><Image Source="/Assets/Images/small_down.png" Stretch="Uniform" HorizontalAlignment="Right"VerticalAlignment="Center" Margin="0 0 10 0" Width="15" Height="15"/><Popup x:Name="PART_Popup" AllowsTransparency="True" IsOpen="{Binding IsSubmenuOpen,RelativeSource={RelativeSource TemplatedParent}}"Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimation}}"><Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}"><ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden"><Grid><ItemsPresenter x:Name="ItemsPresenter"/></Grid></ScrollViewer></Border></Popup></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsHighlighted" Value="True"><Setter Property="Background" TargetName="border" Value="#524E4F"/><Setter Property="BorderBrush" TargetName="border" Value="#524E4F"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

对比如下所示:

在这里插入图片描述
想要二级菜单显示,我们需要把二级菜单样式写出来才能看到,这里我们和一级菜单逻辑一样,先实现无子项的菜单样式 ChildMenuItemStyle 。同样二级面板和一级的无子项样式类似,复制改造后 ChildMenuItemStyle 样式如下所示:

 <Style x:Key="ChildMenuItemStyle" TargetType="{x:Type MenuItem}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type MenuItem}"><Border x:Name="border" BorderThickness="0"Background="{Binding Path=Background,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Menu}}}"Height="{TemplateBinding Height}"Width="{TemplateBinding Width}" ><Grid><ContentPresenter ContentSource="Icon" HorizontalAlignment="Left"VerticalAlignment="Center" Height="16"Width="16" Margin="8 0 0 0"/><ContentPresenter ContentSource="Header" HorizontalAlignment="Left"VerticalAlignment="Center" TextBlock.Foreground="{TemplateBinding Foreground}"TextBlock.FontFamily="{TemplateBinding FontFamily}"TextBlock.FontSize="{TemplateBinding FontSize}"Margin="30 0 0 0"/><!--菜单选中时左侧增加高亮竖线效果--><Grid x:Name="HeightLine" Height="{TemplateBinding Height}" Width="2" Background="White" HorizontalAlignment="Left" VerticalAlignment="Center" Visibility="Collapsed"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsHighlighted" Value="True"><Setter Property="Background" TargetName="border" Value="#524E4F"/><Setter Property="BorderBrush" TargetName="border" Value="#524E4F"/><Setter Property="Visibility" TargetName="HeightLine" Value="Visible"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

然后我们使用有子项菜单样式看看例子效果:

在这里插入图片描述

4、总结

到这,我么其实已经实现了一个二级菜单的全部功能,无非就是 MenuItem 的嵌套。对WPF上位机开发感兴趣的小伙伴可以点击关注和收藏,又想要实现的功能特效欢迎留言,本人不定时按照需求推出更多案例,下一节,将讲完整个下拉菜单的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1263.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024快手面试算法题-生气传染

问题描述 思路分析 生气只会向后传播&#xff0c;最后一个生气的人一定是最长连续没有生气的人中的最后一个人&#xff0c;前提是前面得有一个人生气。 注意&#xff0c;一次只能传播一个人&#xff0c;比如示例1&#xff0c;第一次只会传播给第一个P&#xff0c;不会传播给第…

powerlaw:用于分析幂律分布的Python库

引言 幂律分布在游戏行业中非常重要。在免费游戏模式下&#xff0c;玩家的付费行为往往遵循幂律分布。少数“鲸鱼玩家”贡献了大部分的收入&#xff0c;而大多数玩家可能只进行少量或不进行付费。通过理解和应用幂律分布&#xff0c;游戏开发者可以更好地分析和预测玩家行为&a…

Pr 视频效果:透视

效果面板/视频效果/透视 Video Effects/Perspective Adobe Premiere Pro 的视频效果中&#xff0c;透视 Perspective效果组主要用于在二维平面的视频剪辑中模拟三维空间的透视效果。 通过调整这些效果&#xff0c;可以改变图像的视角、添加阴影、创造立体感&#xff0c;增强画面…

使用 Python 中的 pydub实现 M4A 转 MP3 转换器

在现代数字生活中&#xff0c;我们常常需要处理不同格式的音频文件。今天&#xff0c;我将与大家分享一个简单的 Python 项目&#xff0c;它使用 wxPython 创建一个图形用户界面&#xff08;GUI&#xff09;应用程序&#xff0c;能够将 .m4a 文件转换为 .mp3 文件。这个项目还将…

【Linux】进程状态相关知识详细梳理

0. 预备知识 系统调用和库函数概念 在开发角度&#xff0c;操作系统对外会表现为一个整体&#xff0c;但是会暴露自己的部分接口&#xff0c;供上层开发使用&#xff0c;这部分由操作系统提供的接口&#xff0c;叫做系统调用。 系统调用在使用上&#xff0c;功能比较基础&#…

unity搭建场景学习

unity搭建场景学习 创建场景创建gameobject创建材质&#xff0c;用于给gameobject上色拖拽材质球上色上色原理设置多个材质方式设置贴图的方式 效果设置光滑度一些预览设置菜单渲染模型与碰撞模型网格渲染参数1. materials(材质)2. lighting(光照)3. reflection probes(反射探针…

【Linux】文件系统

目录 1、认识硬件--磁盘 2、文件系统 3、软链接&&硬链接 1、认识硬件--磁盘 唯一的一个机械设备&#xff0c;也是一个外设。 我们可以把磁盘看作是由无数个扇区构成的存储介质。 要把数据存到磁盘&#xff0c;第一个要解决的问题是定位一个扇区&#xff1a;哪一面&…

Linux进阶

认识root用户(超级管理员) root账号:超级管理员账户,在任何地方都有最高权限 其它账户: 是由root权限创建来的.只能在自己的家目录用更大的权限. su和exit(切换/退出) su - 用户名 : 切换到其它用. -加载环境变量 exit 登出当前用户. 可以使用ctrl d 快捷键在前面&#xff…

单臂路由实现不同VLAN之间设备通信

转载请注明出处 本实验为单臂路由配置&#xff0c;目的为让不同VLAN之间的设备能够互相通信。 1.首先&#xff0c;按照要求配置两个pc的ip地址&#xff0c;以pc0为例子&#xff1a; 2在交换机创建vlan10和vlan20 3.划分vlan&#xff0c;pc0为vlan10的设备&#xff0c;pc1为vla…

AR基础知识:SLAM同时定位和构图

在第一部分中&#xff0c;我们了解了算法如何识别相机帧中的关键点。这些是跟踪和识别环境的基础。 对于增强现实&#xff0c;设备必须知道更多信息&#xff1a;它在世界上的 3D 位置。它通过自身与多个关键点之间的空间关系来计算这一点。这个过程称为“同时定位和地图构建”…

【数据结构-邻项消除】力扣2211. 统计道路上的碰撞次数

在一条无限长的公路上有 n 辆汽车正在行驶。汽车按从左到右的顺序按从 0 到 n - 1 编号&#xff0c;每辆车都在一个 独特的 位置。 给你一个下标从 0 开始的字符串 directions &#xff0c;长度为 n 。directions[i] 可以是 ‘L’、‘R’ 或 ‘S’ 分别表示第 i 辆车是向 左 、…

[实战-11] FlinkSql 设置时区对TIMESTAMP和TIMESTAMP_LTZ的影响

table.local-time-zone table.local-time-zoneDataStream-to-Table Conversion&#xff08;拓展知识&#xff09;代码测试flinksql代码执行结果截图1. Asia/Shanghai 结果如下2. UTC结果如下 table.local-time-zone table.local-time-zone可用于设置flinksql的时区。 flink的内…

通过哪些性能指标来评估微调后的大模型实际业务效果?【大模型行业应用落地系列】

ct) 大模型应用场景探讨 ● 通过哪些性能指标来评估微调后的大模型实际业务效果&#xff1f; **【议题说明】**本议题主要探讨评估微调后大模型在实际业务场景中效果的性能指标&#xff0c;确保模型优化与业务目标一致。探讨该议题对用户企业具有多方面的价值&#xff0c;精确…

12-Docker发布微服务

12-Docker发布微服务 Docker发布微服务 搭建SpringBoot项目 新建一个SpringBoot项目 选择依赖项Spring Web和Spring Boot Actuator 在com.qi.docker_boot下创建controller目录&#xff0c;并在该目录下创建OrderController的java类 OrderControllerjava类的内容如下&#xf…

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用 目录 文章目录 【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用目录摘要研究背景问题与挑战如何解决创新点算法模型1. 知识总结模块&#xff08;Knowledge Summarization Module&…

HTML CSS

目录 1. 什么是HTML 2. 什么是CSS ? 3. 基础标签 & 样式 3.1 新浪新闻-标题实现 3.1.1 标题排版 3.1.1.1 分析 3.1.1.2 标签 3.1.1.3 实现 3.1.2 标题样式 3.1.2.1 CSS引入方式 3.1.2.2 颜色表示 3.1.2.3 标题字体颜色 3.1.2.4 CSS选择器 3.1.2.5 发布时间字…

应用在汽车控制系统安全气囊的爱普生可编程晶振SG-8018CG

在汽车安全领域&#xff0c;安全气囊是保护驾乘人员生命安全的关键防线。而作为安全气囊控制系统的关键元件 —— 爱普生可编程晶振 SG - 8018CG&#xff0c;以其卓越的性能成为汽车安全的坚实守护者。 一、高精度频率输出&#xff1a;安全气囊触发的精准之选 在汽车安全气囊控…

第112届全国糖酒会(3月成都)正式官宣!

作为食品饮料行业内备受瞩目的年度盛事&#xff0c;全国糖酒商品交易会&#xff08;简称“糖酒会”&#xff09;一直是各大厂商与经销商展现企业风采、寻觅合作伙伴及签署订单的关键舞台。2024年10月31日&#xff0c;第111届全国糖酒商品交易会&#xff08;秋糖&#xff09;在深…

【Javaee】网络原理-http协议(二)

前言 上一篇博客初步介绍了抓包工具的安装及使用&#xff0c;介绍了http请求报文与响应报文的格式。​​​​​​【Javaee】网络原理—http协议&#xff08;一&#xff09;-CSDN博客 本篇将详细介绍http的方法和http报文中请求头内部键值对的含义与作用&#xff0c;以及常见状…

Python实现摇号系统:详细指南与案例解析

目录 一、摇号系统的基本概念与原理 二、摇号系统的准备工作 三、摇号系统的详细实现步骤 1. 数据读取 2. 随机摇号 3. 结果存储 4. 结果查询 5. 主函数 四、案例解析 五、常见问题与解答 如何确保摇号过程的公平性&#xff1f; 如何处理大量用户数据&#xff1f; …