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

举报
愚公搬代码 发表于 2023/09/30 23:49:45 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#等编程语言来创建个性化的用户界面元素。自定义控件可以根据需求提供更多的功能和自定义化选项,以及更好的用户体验。

🚀一、Menu控件详解

WPF中的Menu控件用于显示应用程序的菜单栏。Menu控件通常用于顶层窗口或主窗口中,以提供应用程序功能的导航。Menu控件的常见用法是在菜单中定义菜单项,然后关联菜单项和命令,使用户能够通过单击菜单项来执行命令。

以下是一些Menu控件的属性:

  • Items:MenuItems的集合,控制菜单的内容。
  • IsMainMenu:指定是否应将菜单作为应用程序的主菜单。
  • Visibility:指定是否应显示菜单。默认为Visible。

以下是一个简单的Menu控件示例:

<Menu IsMainMenu="True">
  <MenuItem Header="_File">
    <MenuItem Header="_New"/>
    <MenuItem Header="_Open"/>
    <MenuItem Header="_Save"/>
    <MenuItem Header="_Exit"/>
  </MenuItem>
  <MenuItem Header="_Edit">
    <MenuItem Header="_Cut"/>
    <MenuItem Header="_Copy"/>
    <MenuItem Header="_Paste"/>
  </MenuItem>
  <MenuItem Header="_Help">
    <MenuItem Header="_About"/>
  </MenuItem>
</Menu>

此示例包含三个菜单项:文件、编辑和帮助。每个菜单项都包含一个或多个子菜单项,用于执行操作或导航到其他部分。用户可以通过单击菜单项来打开子菜单或执行操作。

🔎1.属性介绍

WPF中Menu控件的属性包括:

  1. IsMainMenu:指示当前Menu控件是否是应用程序的主菜单。

  2. IsCheckable:指示是否可以勾选Menu项。

  3. IsCheckable:指示当前Menu项是否被勾选。

  4. IsSubmenuOpen:指示当前Menu项是否打开了子菜单。

  5. InputGestureText:表示与菜单项关联的按键组合。

  6. Command:表示与菜单项关联的命令。

  7. ItemsSource:表示Menu项的数据源。

  8. ItemContainerStyle:表示Menu项的样式。

  9. ItemTemplate:表示Menu项的模板。

  10. Orientation:表示Menu项的排列方式,水平或垂直。

🔎2.常用场景

WPF中Menu控件常用于实现应用程序的菜单功能。以下是一些常见的场景:

  1. 顶部菜单栏:在应用程序窗口的顶部放置一个菜单栏,用户可以点击菜单项打开不同的窗口或执行不同的操作。

  2. 上下文菜单:当用户右键单击某个控件时,弹出该控件的上下文菜单,用户可以从菜单中选择不同的操作。

  3. 快捷键菜单:为了提高应用程序的操作效率,可以为菜单项设置快捷键,让用户通过键盘快速执行相应的操作。

  4. 动态菜单:根据用户的不同权限或当前的系统状态,动态地生成菜单项,让用户只能看到自己有权限或当前可执行的操作。

  5. ToolBar菜单:在工具栏上放置一些常用的操作,用户可以通过点击相关的按钮快速执行相应的操作。

Menu控件是实现应用程序菜单功能的重要控件,可以提高应用程序的易用性和操作效率。

🔎3.具体案例

🦋3.1 静态菜单

<Window x:Class="WpfAppTest.MenuWindow"
        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="MenuWindow" Height="450" Width="800">
        <Window.Resources>
                <!--定义命令-->
                <RoutedUICommand x:Key="cmdRole" />
                <RoutedUICommand x:Key="cmdUser" />
        </Window.Resources>
        <!--输入绑定  Key   Mouse-->
        <Window.InputBindings>
                <KeyBinding Command="{StaticResource cmdRole}" Gesture="Ctrl+R" />
        </Window.InputBindings>
        <!--将命令与处理程序关联起来-->
        <Window.CommandBindings>
                <CommandBinding Command="{StaticResource cmdRole}" Executed="MiRole_Click"/>
                <CommandBinding Command="{StaticResource cmdUser}" Executed="MiUser_Click"/>
        </Window.CommandBindings>
    <Grid>
                <Menu Height="30" VerticalAlignment="Top" IsMainMenu="False" >
                        <MenuItem Header="系统管理">
                                <!--<MenuItem Name="miRole" Header="角色管理" Click="MiRole_Click"/>-->
                                <MenuItem Name="miRole" Header="角色管理" Command="{StaticResource cmdRole}" InputGestureText="Ctrl+R">
                                        <!--设置图标-->
                                        <MenuItem.Icon>
                                                <Image Source="imgs/1111.jpg"/>
                                        </MenuItem.Icon>
                                </MenuItem>
                                <MenuItem Header="用户管理" Command="{StaticResource cmdUser}"/>
                                <MenuItem Header="菜单管理"/>
                                <MenuItem Header="权限管理"/>
                        </MenuItem>
                        <MenuItem Header="基础资料">
                                <MenuItem Header="商品管理">
                                        <MenuItem Header="商品类别管理"/>
                                        <MenuItem Header="商品信息管理"/>
                                </MenuItem>
                                <MenuItem Header="仓库管理"/>
                                <MenuItem Header="单位管理"/>
                                <MenuItem Header="期初入库设置"/>
                        </MenuItem>
                        <MenuItem Header="业务管理">
                                <MenuItem Header="采购入库"/>
                                <MenuItem Header="销售出库"/>
                        </MenuItem>
                        <MenuItem Header="查询中心">
                                <MenuItem Header="采购查询">
                                        <MenuItem Header="按供应商采购统计"/>
                                        <MenuItem Header="按仓库采购统计"/>
                                        <MenuItem Header="按商品采购统计"/>
                                </MenuItem>
                                <MenuItem Header="销售查询"/>
                                <MenuItem Header="库存查询"/>
                                <MenuItem Header="单据查询"/>
                        </MenuItem>
                </Menu>
    </Grid>
</Window>

/// <summary>
/// 打开角色管理页面
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MiRole_Click(object sender, RoutedEventArgs e)
{
        RoleWindow roleWin = new RoleWindow();
        roleWin.Show();
}

private void MiUser_Click(object sender, RoutedEventArgs e)
{
        UserManageWindow userWin = new UserManageWindow();
        userWin.Show();
}

🦋3.2 动态菜单

<Window x:Class="WpfAppTest.MenuWindow1"
        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="MenuWindow1" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid>
                <Menu HorizontalAlignment="Left" Height="30" Margin="0" VerticalAlignment="Top" BorderBrush="LightBlue" BorderThickness="1"  ItemsSource="{Binding MenuList}">
                        <Menu.ItemContainerStyle>
                                <Style TargetType="{x:Type MenuItem}">
                                        <Setter Property="InputGestureText" Value="{Binding MKey}"/>
                                        <Setter Property="Command" Value="{Binding MICommand}"/>
                                </Style>
                        </Menu.ItemContainerStyle>
                        <Menu.ItemTemplate>
                                <HierarchicalDataTemplate DataType="{x:Type model:MenuItemModel}" ItemsSource="{Binding SubItems}">
                                        <TextBlock Text="{Binding MenuName}" VerticalAlignment="Center"/>
                                </HierarchicalDataTemplate>
                        </Menu.ItemTemplate>
                     
                </Menu>

        </Grid>
</Window>

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

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
                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;
                        miInfo.MKey = mi.MKey;
                        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,MKey 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"];
                        menu.MKey = dr["MKey"].ToString();
                        list.Add(menu);
                }
                dr.Close();
                return list;
        }
}

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; }
}


//菜单项绑定实体
public class MenuItemModel
{
        public int MenuId { get; set; }
        public string MenuName { get; set; }
        public string MKey { get; set; }

        public List<MenuItemModel> SubItems { get; set; }
        public MenuItemModel()
        {
                SubItems = new List<MenuItemModel>();
        }
        public ICommand MICommand
        {
                get
                {
                        return new RelayCommand(o =>
                        {
                                MessageBox.Show(MenuName);
                        });
                }
        }
}

🚀感谢:给读者的一封信

亲爱的读者,

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

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

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

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

在这里插入图片描述

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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