(文章目录)


前言

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