wpf多级动态右键菜单ContextmMenu

本文探讨了在WPF中如何实现多级动态右键菜单,对比了ContextMenuStrip和ContextMenu的区别,并提供了使用ContextMenuStrip和ContextMenu两种方法的实现示例。在WPF中,虽然ContextMenuStrip更方便,但考虑到性能和安全性,使用内置的ContextMenu也是不错的选择。要注意,使用ContextMenu时,需要为列表项单独添加事件处理。


         搞这个右键菜单用了挺长的时间,一是网络上面资料比较少,二是里面有坑,坑就是众所周知,c#程序有两种窗口,一种是Form窗口,另一种是wpf窗口。网上的资料是这两种混合,开始我并没有意识到这两种有多大的差别,但是看了许多资料发现有很多自相矛盾的地方,因为这两种窗口有很多不同的地方:
  • Formcontextmenustrip已经替代了contextmenu,但是contextmenu仍然可以用。
  • Wpf:只能使用contextmenu

 

contextmenucontextmenudtrip有以下几种区别:

1】可以将ContextMenuStrip 与任何控件关联,单击鼠标右键会自动显示快捷菜单。

2】可以通过使用 Show 方法以编程方式显示 ContextMenuStrip

3ContextMenuStrip支持可取消的 Opening Closing 事件以处理动态填充和多次单击方案。

4ContextMenuStrip支持图像、菜单项复选状态、文本、访问键、快捷键和级联菜单。 

尽管 ContextMenuStrip 对以前版本的ContextMenu 控件的功能进行了替换和添加,但考虑到向后兼容性和将来的使用(如果的确需要),仍然保留了 ContextMenu

建议采用ContextMenuStrip

Form我没有研究,写一下wpf右键菜单实现方式。


     强行使用contextmenustrip

      虽然wpf不能加contextmenustrip控件,但是可以在右键单击响应里使用show显示出来。好处是比较方便,可以随意控制子菜单项,而且contextmenustrip可以随意加图片等其他部分。

实例如下:

1.简单添加

<span style="font-size:14px;">((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems.Add("正常");

((ToolStripDropDownItem)(((ToolStripDropDownItem)contextMenuStrip1.Items[

或:

ToolStripDropDownItem ts 
= ((ToolStripDropDownItem)contextMenuStrip1.Items["aToolStripMenuItem"]);
            ts = ((ToolStripDropDownItem)ts.DropDownItems["eToolStripMenuItem"]);
            ts.DropDownItems.Add(new ToolStripMenuItem("h"));"aToolStripMenuItem"]).DropDownItems["eToolStripMenuItem"])).DropDownItems.Add(new ToolStripMenuItem("h"));
((ToolStripDropDownItem)(((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems[1])).DropDownItems.Add("OK");
            contextMenuStrip1.Items.Add("编辑");
            contextMenuStrip1.Items.Add("状态");
            ((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems.Add("正常");
            ((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems.Add("维修");
            ((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems.Add("建设中");
            ((ToolStripDropDownItem)(((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems[0])).DropDownItems.Add("hi");
            ((ToolStripDropDownItem)(((ToolStripDropDownItem)(((ToolStripDropDownItem)contextMenuStrip1.Items[1]).DropDownItems[0])).DropDownItems[0])).DropDownItems.Add("hao hi");</span>

动态添加的方法为:

 int count = dt.Rows.Count;
            ToolStripItem[] Tsi = new ToolStripItem[count];
            for(int i=0;i<count;i++)
           {
               this.contextMenuStrip2.Items.Add(dt.Rows[i]["ReportFormat"].ToString());
               this.contextMenuStrip2.Items[i].Click += new EventHandler(ts_1_click);    //对应的点击事件
           }
            contextMenuStrip2.Show(btPrint, 0, btPrint.Height);
        }
在contextmenustrip中,可以直接使用这样的方式contextmenustrip.Items[1]指代这个菜单项的子项,在动态添加时特别方便。

     使用contextmenu

这个的好处是使用wpf自带的控件,安全性和性能/速度上都有优势,但是不如contextmenu那么灵活。实例如下:

	/************************************************************************************************/
	// 项目人员列表右键单击
			private void list_project_staff_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
			{
				// 添加删除人员菜单项
				//System.Windows.Controls.MenuItem menuitem_delete_staff = new System.Windows.Controls.MenuItem();
				//menuitem_delete_staff.Header = "删除人员";
				//menuitem_delete_staff.Click += delete_project_staff;
				//contextmenu_list_staff.Items.Clear();
				if (list_project_staff.SelectedIndex > -1) {
					menuitem_delete_staff.Visibility = System.Windows.Visibility.Visible;
				} else {
					menuitem_delete_staff.Visibility = System.Windows.Visibility.Collapsed;
				}
				// 动态添加人员菜单项
				menuitem_add_staff.Items.Clear();
				for (int i = 0; i < data.list_other_project_staff.Count; i++) {
					System.Windows.Controls.MenuItem menuitem_add = new System.Windows.Controls.MenuItem();
					menuitem_add.Header = data.list_other_project_staff[i].name;
					menuitem_add.Click += add_project_staff;
					menuitem_add_staff.Items.Add(menuitem_add);
				}
			}
	
	// 响应:添加
	private void add_project_staff(object sender, RoutedEventArgs e)
	{
		System.Windows.Controls.MenuItem menu = (sender as System.Windows.Controls.MenuItem);
		string name = menu.Header.ToString();
		// 发送数据
		try {
			this.server.send_package(new uplink_update_project_staff() {
				project_ID = data.list_project[listbox_display_projects.SelectedIndex].ID,
				staff_ID = data.list_other_project_staff.Find(x => x.name == name).ID,
				action = 1,
			});
		} catch {

		}
	}
	/*************************************************************************************************/

还有一点需要注意的是,将按钮事件放在Listbox时,如果选中了其中一向,并不会触发事件,所以需要给每一项也添加事件。可以看到contextmenu并不能使用Items[1]的方式指代菜单项。









ModernUI(http://mui.codeplex.com/)是一个开源的WPF界面库,利用该界面库,我们可以创建很酷的应用程序。下面是ModernUI官方示例,你可以从官方网站直接下载源码运行,如果是.NET 4.0的话,记得要声明“NET4”预编译变量,否则无法编译通过。 这个界面框架是基于ModernUI来实现的,在该文我将分享所有的源码,并详细描述如何基于ModernUI来构造一个非常通用的、插件化的WPF开发框架。下载源码的同志,希望点击一下推荐。 本文将按照以下四点来介绍: (1)ModernUI简介; (2)构建通用界面框架的思路; (3)基于ModernUI和OSGi.NET的插件化界面框架实现原理及源码分析; (4)其它更有趣的东西~~。 要编写这样的WPF界面,我们需要在一个Window上声明菜单和Tab页面,下图是定义菜单的声明。 此外,每一个Tab风格页面,你也需要手动的为菜单创建这样的界面元素。 直接用这样的方式来使用ModernUI,显然不太适合团队协作性的并行开发,因为在一个团队的协作中,不同的人需要完成不同的功能,实现不同页面,每个人都需要来更改主界面。 我非常希望模块化的开发方法,因为这可以尽可能的复用现有资产,使程序员可以聚焦在自己关注的业务逻辑上,不需要关心UI的使用。下面,我将来描述基于ModernUI实现的一个通用界面框架,这个界面框架允许程序员在自己的业务模块中配置需要显示的界面元素。 通用界面框架实现思路: 我希望能够实现这样的通用界面框架: (1)程序员可以直接实现需要展现业务逻辑的界面,不需要关注如何使用ModernUI; (2)程序员可以通过简单的配置就可以将自己实现的业务逻辑页面显示在主界面中; (3)这个界面框架可以完全复用。 当我看到ModernUI这个界面库时,我希望将应用程序做成模块化,每一个模块能够: (1)通过以下配置能够直接显示二级菜单。 (2)通过以下配置能够直接显示三级菜单。 这样做的好处是,开发插件的时候可以不需要关心界面框架插件;团队在协作开发应用的时候,可以独立开发并不需要修改主界面;团队成员的插件可以随时集成到这个主界面;当主界面无法满足我们的布局时或者用户需求无法满足时,可以直接替换主界面框架而不需要修改任何插件代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值