locked
Cancel uncheked menuitem RRS feed

  • Question

  • Hello, I have a menu with many menuitem, which have a "groupname" to select only one (multi-language). I need that when clicking on one that is checked, the click is canceled and thus to be able to avoid that it is unchecked

        public class MenuItemExtensions : DependencyObject
        {
            private static readonly 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 menuItem, string value)
            {
                menuItem.SetValue(GroupNameProperty, value);
            }
    
            public static string GetGroupName(MenuItem menuItem)
            {
                return menuItem.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)
                {
                    var newGroupName = e.NewValue.ToString();
                    var oldGroupName = e.OldValue.ToString();
    
                    if (string.IsNullOrEmpty(newGroupName))
                    {
                        //Removing the toggle button from grouping
                        RemoveMenuItemFromGrouping(menuItem);
                    }
                    else
                    {
                        //Switching to a new group
                        if (newGroupName != oldGroupName)
                        {
                            if (!string.IsNullOrEmpty(oldGroupName))
                            {
                                //Remove the old group mapping
                                RemoveMenuItemFromGrouping(menuItem);
                            }
                            ElementToGroupNames.Add(menuItem, e.NewValue.ToString());
                            menuItem.Checked += MenuItemChecked;
                            menuItem.PreviewMouseLeftButtonDown += PreviewMouseLeftButtonDown;
                        }
                    }
                }
            }
    
            private static void RemoveMenuItemFromGrouping(MenuItem menuItem)
            {
                ElementToGroupNames.Remove(menuItem);
                menuItem.Checked -= MenuItemChecked;
                menuItem.PreviewMouseLeftButtonDown -= PreviewMouseLeftButtonDown;
            }
    
            private static void PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
            {
                var menuItem = sender as MenuItem;
    
                if (menuItem != null && menuItem.IsChecked)
                {
                    e.Handled = true;
                    menuItem.IsChecked = true;
                }
            }
    
            private static void MenuItemChecked(object sender, RoutedEventArgs e)
            {
                var menuItem = e.OriginalSource as MenuItem;
    
                foreach (var item in ElementToGroupNames)
                {
                    if (!Equals(item.Key, menuItem) && item.Value == GetGroupName(menuItem))
                    {
                        item.Key.IsChecked = false;
                    }
                }
            }
        } 
    

    • Edited by HajimeSaito Wednesday, February 8, 2017 2:10 AM
    Wednesday, February 8, 2017 2:10 AM

Answers


  • Hi HajimeSaito,

    >>I need that when clicking on one that is checked, the click is canceled and thus to be able to avoid that it is unchecked

    I have made a sample on my side. You can try the following code.

    public class MenuItemExtensions : DependencyObject
        {
            public static MenuItem currentselect;
    
            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;
                            menuItem.Unchecked += MenuItemUnchecked;
                        }
                    }
                }
            }
    
            private static void RemoveCheckboxFromGrouping(MenuItem checkBox)
            {
                ElementToGroupNames.Remove(checkBox);
                checkBox.Checked -= MenuItemChecked;
                checkBox.Unchecked -= MenuItemUnchecked;
            }
    
            private static void MenuItemUnchecked(object sender, RoutedEventArgs e)
            {
                var menuItem = e.OriginalSource as MenuItem;
    
                if (currentselect != null)
                {
                    if (currentselect == menuItem && currentselect.GetValue(GroupNameProperty).ToString() == GetGroupName(menuItem))
                    {
                        menuItem.IsChecked = true;
                    }
                }
            }
    
            static void MenuItemChecked(object sender, RoutedEventArgs e)
            {
                var menuItem = e.OriginalSource as MenuItem;
                currentselect = menuItem;
                foreach (var item in ElementToGroupNames)
                {
                    if (item.Key != menuItem && item.Value == GetGroupName(menuItem))
                    {
                        item.Key.IsChecked = false;
                    }
                }
            }
        }

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by HajimeSaito Wednesday, February 8, 2017 4:31 PM
    Wednesday, February 8, 2017 5:12 AM