• 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

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

  • 相关阅读:
    Delegte的BeginInvoke
    C# socket 实现客户端连续发送数据
    Button的PerformClick()
    Invoke和BeginInvoke
    Application.DoEvents() 处理队列消息,防界面假死
    BackgroundWorker后台线程
    CF773F
    ORM框架,没必要搞那么复杂
    VS Unable to copy file
    Unbuntu auto start program
  • 原文地址:https://www.cnblogs.com/mq0036/p/12371140.html
Copyright © 2020-2023  润新知