WPF动态加载Menu菜单

有一个项目动态加载wpf的菜单控件可以非常有效的做到更具用户权限显示或控制MenuItem菜单,如何实现这种功能,其实也非常简单。

  首先需要了解Wpf的menu菜单控件,她的结构其实也非常简单

<Menu DockPanel.Dock="Top" Name="MenuOptionGroup">
    <MenuItem Header="菜单1">
        <MenuItem Header="内容1">
        </MenuItem>                
    </MenuItem>    
    <MenuItem Header="菜单2">       
    </MenuItem>            
 </Menu>

 

  

这是其最基本的结构,menu是其菜单主体,menu下面有menuitem,menuitem可以无限的放入menuitem.

 

具体思路:

获取需要的显示菜单数据(数据需要拥有父id字段,就是这个menitem的上一级menuitem的id),通过先查询出menuitem数据的父id字段为0的menuitem的数据(就是menuitem没有上一级菜单的菜单项目)Add加载menuitem 到menu。然后继续拿到此的id来做查询出是否还有父id的数为此id的,如果有就继续下去,没有则给menuitem 注册一个click事件,用于点击菜单项目做相应的操作。

 

数据库表设计:

 

具体实现方法:

复制代码
public List<MenuItem> menuItems = new List<MenuItem>();
public MainIndex()
        {
            InitializeComponent();
            SetMenus();
            foreach (var item in menuItems)
            {
                MenuOptionGroup.Items.Add(item);
            }
        }
private void SetMenus()
        {
            List<GblMenu> lstMenus = lstGblMenuItem.Where(t => t.PaterId == 0).ToList();
            foreach (GblMenu item in lstMenus)
            {
                MenuItem menuItem = new MenuItem();
                menuItem.Header = item.MenuName;
                menuItem.Name = item.ItemName;
                menuItem = SetMenuItems(menuItem, item.Id);
                menuItems.Add(menuItem);
            }
        }
        private MenuItem SetMenuItems(MenuItem menuItem, int PatId)
        {
            List<GblMenu> lstMenuItems = lstGblMenuItem.Where(t => t.PaterId == PatId).ToList();
            foreach (GblMenu item in lstMenuItems)
            {
                MenuItem menuItems = new MenuItem();
                menuItems.Header = item.MenuName;
                menuItems.Name = item.ItemName;
 
                menuItem.Items.Add(menuItems);
                if (!lstGblMenuItem.Where(t => t.PaterId == item.Id).ToList().Any())
                {
                    menuItems.Click += MenuItems_Click;
                }
                SetMenuItems(menuItems, item.Id);
            }
            return menuItem;
        }
复制代码

 

效果:

结语:

其实这只是其中一个方法,且这种方法也适用与Winform,都是同一个套路。

 

出处:https://blog.csdn.net/weixin_42084199/article/details/95042521

========================================================================

WPF动态创建右键菜单

第一步:菜单接口定义

复制代码
public interface IMenuItem
    {
        /// <summary>
        /// 图标
        /// </summary>
        string ImageURL { get; set; }
 
        /// <summary>
        /// 名称
        /// </summary>
        string Caption { get; set; }
 
        /// <summary>
        /// 是否开始分组
        /// </summary>
        bool IsBeginGroup { get; set; }
 
        /// <summary>
        /// 是否可用
        /// </summary>
        bool IsEnable { get; set; }
 
        /// <summary>
        /// 是否可见
        /// </summary>
        bool IsVisible { get; set; }
 
        /// <summary>
        /// 子菜单集合
        /// </summary>
        List<IMenuItem> SubMenus { get; }
 
        /// <summary>
        /// 执行菜单
        /// </summary>
        void ExcuteItem(object OperObj);
    }
复制代码

 

第二步:实现菜单接口

复制代码
public class MyMeunItem : IMenuItem
    {
        private Action<object> _action;
        public MyMeunItem()
        {
            m_SubMenus = new List<IMenuItem>();
        }
 
        public MyMeunItem(Action<object> action)
        {
            _action = action;
            m_SubMenus = new List<IMenuItem>();
        }
 
        private string m_Caption = "菜单";
        public string Caption
        {
            get
            {
                return m_Caption;
            }
 
            set
            {
                m_Caption = value;
            }
        }
 
        public string ImageURL
        {
            get;
            set;
        }
 
        private bool m_IsBeginGroup;
        public bool IsBeginGroup
        {
            get
            {
                return m_IsBeginGroup;
            }
 
            set
            {
                m_IsBeginGroup = value;
            }
        }
 
        private bool m_IsEnable = true;
        public bool IsEnable
        {
            get
            {
                return m_IsEnable;
            }
 
            set
            {
                m_IsEnable = value;
            }
        }
 
        private bool m_IsVisible = true;
        public bool IsVisible
        {
            get
            {
                return m_IsVisible;
            }
 
            set
            {
                m_IsVisible = value;
            }
        }
 
        private List<IMenuItem> m_SubMenus;
        public List<IMenuItem> SubMenus
        {
            get
            {
                return m_SubMenus;
            }
        }
 
        public void ExcuteItem(object OperObj)
        {
            if (_action != null)
            {
                _action(OperObj);
            }
            else
            {
                MessageBox.Show("MyMenu Do...");
            }
        }
    }
复制代码

 

第三步:自定义控件,添加菜单依赖属性(以button为例)

复制代码
public class MyCustomButton : Button
    { 
        static MyCustomButton()
        {
        }
 
        public ObservableCollection<IMenuItem> MenuItems
        {
            get { return (ObservableCollection<IMenuItem>)GetValue(MenuItemsProperty); }
            set { SetValue(MenuItemsProperty, value); }
        }
 
        public static readonly DependencyProperty MenuItemsProperty =
            DependencyProperty.Register("MenuItems",
                typeof(ObservableCollection<IMenuItem>),
                typeof(MyCustomButton),
                new PropertyMetadata(null, new PropertyChangedCallback(MenuItemsChanged)));
 
        private static void MenuItemsChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                MyCustomButton dropButton;
                if (dpObj is MyCustomButton)
                    dropButton = dpObj as MyCustomButton;
                else
                    return;
 
                dropButton.ContextMenu = new ContextMenu();
                ObservableCollection<IMenuItem> colItems = (ObservableCollection<IMenuItem>)dpObj.GetValue(MenuItemsProperty);
                if (colItems == null)
                    return;
 
                foreach (var item in colItems)
                {
                    MenuItem menuItem = new MenuItem()
                    {
                        Header=item.Caption,
                        Icon = item.ImageURL,
                        IsEnabled = item.IsEnable,
                        Visibility = item.IsVisible ? Visibility.Visible : Visibility.Collapsed,
                        Tag = item
                    };
 
                    menuItem.Click += (obj, arg) => ((obj as MenuItem).Tag as IMenuItem).ExcuteItem(obj);
                    // 是否开始分组
                    if (item.IsBeginGroup)
                    {
                        dropButton.ContextMenu.Items.Add(new Separator());
                    }
 
                    dropButton.ContextMenu.Items.Add(menuItem);
                }
                
                dropButton.ContextMenu.PlacementTarget = dropButton;
                dropButton.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            }
            catch (Exception ex)
            { }
        }
    }
复制代码

 

第四步:XAML中添加该自定义按钮

复制代码
<Window x:Class="DropDownTest.MainWindow"
        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:DropDownTest"
        xmlns:uc="clr-namespace:GtMap.Pro.Package.Controls;assembly=GtMap.Pro.Package.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainFormVM/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="40"></RowDefinition>
        </Grid.RowDefinitions>
        <uc:MyCustomButton Grid.Row="0" MenuItems="{Binding MenuItems}" Content="下拉按钮" Margin="0" Width="60" Height="20"></uc:MyCustomButton>
      
    </Grid>
</Window>
复制代码

 

第五步:ViewModel编写,添加菜单项

复制代码
public class MainFormVM : INotifyPropertyChanged
    {
        public MainFormVM()
        {
            try
            {
                m_MenuItems = new ObservableCollection<IMenuItem>();
                m_MenuItems.Add(new MyMeunItem() { Caption = "菜单1" });
                var item = new MyMeunItem(MenuFunc) { Caption = "菜单2", IsBeginGroup = true };
                m_MenuItems.Add(item);
            }
            catch
            {
            }
        }
 
        private ObservableCollection<IMenuItem> m_MenuItems;
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        public ObservableCollection<IMenuItem> MenuItems
        {
            get
            {
                return m_MenuItems;
            }
 
            set
            {
                m_MenuItems = value;
                PropertyChanged(this, new PropertyChangedEventArgs("MenuItems"));
            }
        }
 
    
        public void MenuFunc(object obj)
        {
            MessageBox.Show("VM VM VM");
        }
    }
 
    public class MyCommand : ICommand
    {
        Action<object> _action;
        public MyCommand(Action<object> action)
        {
            _action = action;
        }
 
        public event EventHandler CanExecuteChanged;
 
        public bool CanExecute(object parameter)
        {
            return true;
        }
 
        public void Execute(object parameter)
        {
            if (_action != null)
                _action(parameter);
        }
    }
复制代码

 

界面效果

 

 

出处:https://blog.csdn.net/xiangqiang2015/article/details/86219674

=====================================================================================

WPF后台动态生成右键菜单

复制代码
#region 循环生成右键菜单
        private ContextMenu ContextMenus(Dictionary<string, RoutedEventHandler> list)
        {
            ContextMenu cm = new ContextMenu();
            Style style = (Style)this.FindResource("ContextMenu"); //定义前台显示模板
            cm.Style = style;
                foreach (var dc in list)
                {
                    MenuItem menu = new MenuItem();
                    menu.Style = (Style)this.FindResource("JjxyMenuItem");
                    menu.Header = dc.Key;
                    menu.Click += dc.Value;
                    cm.Items.Add(menu);
                }
            

            return cm;
        } 
        #endregion
复制代码

需要右键菜单的地方使用:

Dictionary<string, RoutedEventHandler> dist = new Dictionary<string, RoutedEventHandler>();
            //添加右键菜单项,包括名称和事件
            dist.Add("添加", add_Click);
            dist.Add("修改", edit_Click);
            dist.Add("删除", del_Click);
            dist.Add("导出", putout_Click);
            dgrid.ContextMenu = ContextMenus(dist);

 

添加即可,dgrid为DataGrid实例对象,使用字典,string为菜单名,RoutedEventHandler为菜单事件。

 

 

出处:https://www.cnblogs.com/qwhh/p/5356091.html

====================================================================================

posted on   jack_Meng  阅读(9765)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2018-02-27 结构化日志类库 ---- Serilog库
2018-02-27 项目管理上的失误和应对措施
2018-02-27 Android分类导航
2018-02-27 Android破解
2018-02-27 Android开发入门
2018-02-27 安装 Android Studio 2.3 详细过程及错误解决
2018-02-27 Python学习思维导图

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

支付宝打赏

主题色彩