wpf 如何实现动态伸缩菜单?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf 如何实现动态伸缩菜单?相关的知识,希望对你有一定的参考价值。
参考技术A expander控件 ,具体见MSDNWPF动态加载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);
-
}
-
}
界面效果
==
WPF 绑定方式动态创建菜单
以上是关于wpf 如何实现动态伸缩菜单?的主要内容,如果未能解决你的问题,请参考以下文章