相互排斥的可检查菜单项?(Mutually exclusive checkable menu items?)

编程入门 行业动态 更新时间:2024-10-28 19:35:38
相互排斥的可检查菜单项?(Mutually exclusive checkable menu items?)

给出以下代码:

<MenuItem x:Name="MenuItem_Root" Header="Root"> <MenuItem x:Name="MenuItem_Item1" IsCheckable="True" Header="item1" /> <MenuItem x:Name="MenuItem_Item2" IsCheckable="True" Header="item2"/> <MenuItem x:Name="MenuItem_Item3" IsCheckable="True" Header="item3"/> </MenuItem>

在XAML中,是否有创建互相排斥的可检查菜单项的方法? 用户在哪里检查项目2,项目1和3自动取消选中。

我可以通过监视菜单上的单击事件,确定检查哪个项目,并取消选中其他菜单项来完成代码。 我认为有一个更简单的方法。

有任何想法吗?

Given the following code:

<MenuItem x:Name="MenuItem_Root" Header="Root"> <MenuItem x:Name="MenuItem_Item1" IsCheckable="True" Header="item1" /> <MenuItem x:Name="MenuItem_Item2" IsCheckable="True" Header="item2"/> <MenuItem x:Name="MenuItem_Item3" IsCheckable="True" Header="item3"/> </MenuItem>

In XAML, is there a way to create checkable menuitem's that are mutually exclusive? Where is the user checks item2, item's 1 and 3 are automatically unchecked.

I can accomplish this in the code behind by monitoring the click events on the menu, determining which item was checked, and unchecking the other menuitems. I'm thinking there is an easier way.

Any ideas?

最满意答案

这可能不是您要查找的内容,但是您可以为MenuItem类编写一个扩展,使您可以使用类似于RadioButton类的GroupName属性的内容。 我稍微修改了这个方便的示例,用于类似地扩展ToggleButton控件,并针对您的情况稍微修改了一下,并提出了这个问题:

using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; namespace WpfTest { public class MenuItemExtensions : DependencyObject { public static Dictionary<MenuItem, String> ElementToGroupNames = new Dictionary<MenuItem, String>(); public static readonly DependencyProperty GroupNameProperty = DependencyProperty.RegisterAttached("GroupName", typeof(String), typeof(MenuItemExtensions), new PropertyMetadata(String.Empty, OnGroupNameChanged)); public static void SetGroupName(MenuItem element, String value) { element.SetValue(GroupNameProperty, value); } public static String GetGroupName(MenuItem element) { return element.GetValue(GroupNameProperty).ToString(); } private static void OnGroupNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //Add an entry to the group name collection var menuItem = d as MenuItem; if (menuItem != null) { String newGroupName = e.NewValue.ToString(); String oldGroupName = e.OldValue.ToString(); if (String.IsNullOrEmpty(newGroupName)) { //Removing the toggle button from grouping RemoveCheckboxFromGrouping(menuItem); } else { //Switching to a new group if (newGroupName != oldGroupName) { if (!String.IsNullOrEmpty(oldGroupName)) { //Remove the old group mapping RemoveCheckboxFromGrouping(menuItem); } ElementToGroupNames.Add(menuItem, e.NewValue.ToString()); menuItem.Checked += MenuItemChecked; } } } } private static void RemoveCheckboxFromGrouping(MenuItem checkBox) { ElementToGroupNames.Remove(checkBox); checkBox.Checked -= MenuItemChecked; } static void MenuItemChecked(object sender, RoutedEventArgs e) { var menuItem = e.OriginalSource as MenuItem; foreach (var item in ElementToGroupNames) { if (item.Key != menuItem && item.Value == GetGroupName(menuItem)) { item.Key.IsChecked = false; } } } } }

然后,在XAML中,你会写:

<MenuItem x:Name="MenuItem_Root" Header="Root"> <MenuItem x:Name="MenuItem_Item1" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item1" /> <MenuItem x:Name="MenuItem_Item2" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item2"/> <MenuItem x:Name="MenuItem_Item3" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item3"/> </MenuItem>

这有点痛苦,但它提供了不强迫你编写任何额外的程序代码(当然除了扩展类)来实现它的好处。

值得一提的是Brad Cunningham撰写了原版ToggleButton解决方案。

This may not be what you're looking for, but you could write an extension for the MenuItem class that allows you to use something like the GroupName property of the RadioButton class. I slightly modified this handy example for similarly extending ToggleButton controls and reworked it a little for your situation and came up with this:

using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; namespace WpfTest { public class MenuItemExtensions : DependencyObject { public static Dictionary<MenuItem, String> ElementToGroupNames = new Dictionary<MenuItem, String>(); public static readonly DependencyProperty GroupNameProperty = DependencyProperty.RegisterAttached("GroupName", typeof(String), typeof(MenuItemExtensions), new PropertyMetadata(String.Empty, OnGroupNameChanged)); public static void SetGroupName(MenuItem element, String value) { element.SetValue(GroupNameProperty, value); } public static String GetGroupName(MenuItem element) { return element.GetValue(GroupNameProperty).ToString(); } private static void OnGroupNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //Add an entry to the group name collection var menuItem = d as MenuItem; if (menuItem != null) { String newGroupName = e.NewValue.ToString(); String oldGroupName = e.OldValue.ToString(); if (String.IsNullOrEmpty(newGroupName)) { //Removing the toggle button from grouping RemoveCheckboxFromGrouping(menuItem); } else { //Switching to a new group if (newGroupName != oldGroupName) { if (!String.IsNullOrEmpty(oldGroupName)) { //Remove the old group mapping RemoveCheckboxFromGrouping(menuItem); } ElementToGroupNames.Add(menuItem, e.NewValue.ToString()); menuItem.Checked += MenuItemChecked; } } } } private static void RemoveCheckboxFromGrouping(MenuItem checkBox) { ElementToGroupNames.Remove(checkBox); checkBox.Checked -= MenuItemChecked; } static void MenuItemChecked(object sender, RoutedEventArgs e) { var menuItem = e.OriginalSource as MenuItem; foreach (var item in ElementToGroupNames) { if (item.Key != menuItem && item.Value == GetGroupName(menuItem)) { item.Key.IsChecked = false; } } } } }

Then, in the XAML, you'd write:

<MenuItem x:Name="MenuItem_Root" Header="Root"> <MenuItem x:Name="MenuItem_Item1" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item1" /> <MenuItem x:Name="MenuItem_Item2" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item2"/> <MenuItem x:Name="MenuItem_Item3" YourNamespace:MenuItemExtensions.GroupName="someGroup" IsCheckable="True" Header="item3"/> </MenuItem>

It's a bit of a pain, but it offers the perk of not forcing you to write any additional procedural code (aside from the extension class, of course) to implement it.

Credit goes to Brad Cunningham who authored the original ToggleButton solution.

更多推荐

item,菜单,<MenuItem,code,电脑培训,计算机培训,IT培训"/> <meta name="des

本文发布于:2023-08-03 15:07:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1395182.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:菜单项   Mutually   exclusive   items   menu

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!