2021-08-23 WPF控件专题 Menu控件详解

Posted 微软MVP Eleven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-08-23 WPF控件专题 Menu控件详解相关的知识,希望对你有一定的参考价值。

一:静态菜单

1.Menu控件介绍

Menu简介:Windows菜单控件,控件可用于按层次组织与命令和事件处理程序关联的元素
MenuBase:选择项的 — ItemsControl 条目控件

常用属性: IsMainMenu 是否接收主菜单激活通知 true 按alt或f10 激活,如果为false ,不能激活

MenuItem介绍 Menu控件中的可选项 带标题的条目控件

父类:HeaderedItemsControl

Command CommandParameter Icon Header
InputGestureText 快捷键文本

Click事件 Command命令

控件使用(制作一个菜单栏)

2.具体案例

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

二:动态菜单

1.Menu控件介绍

动态生成菜单项 :递归加载菜单数据、分层数据模板

获取菜单数据:按层次结构组织的数据列表

菜单模型:编号 名称 父菜单编号 快捷键

菜单项模型:编号 名称 快捷键 子菜单列表

数据模板:分层数据模板 HeaderedItemsControl Menu TreeView

递归加载菜单的方法,分层数据模板嵌入Menu控件中

效果:菜单栏,菜单项动态加载生成的

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

以上是关于2021-08-23 WPF控件专题 Menu控件详解的主要内容,如果未能解决你的问题,请参考以下文章

2021-08-23 WPF控件专题 TreeView控件详解

2021-08-23 WPF控件专题 ContextMenu 控件详解

2021-08-19 WPF控件专题 TabControl 控件详解

2021-08-17 WPF控件专题 Groupbox 控件详解

2021-08-20 WPF控件专题 DataGrid控件详解

2021-08-13 WPF控件专题 ComboBox 控件详解