From d7e0fcaf21326ea54101cbef0ca6004552661026 Mon Sep 17 00:00:00 2001 From: Jonas Arnold Date: Thu, 6 Apr 2023 12:06:44 +0200 Subject: [PATCH] AllowNoneSelected hinzugefuegt im SingleSelectSubMenu --- MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs b/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs index ea08567..3c3e852 100644 --- a/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs +++ b/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs @@ -12,6 +12,10 @@ namespace MultiTerm.Wpf.Controls; public class SingleSelectSubMenu : MenuItem { + /// + /// Internal marker for when internal unchecking is ongoing. Unchecking events shall then be ignored. + /// + private bool internalUncheckingOngoing = false; #region Static Properties private static readonly Dictionary RegisteredSubItemsAndParent = new(); #endregion @@ -31,6 +35,11 @@ public class SingleSelectSubMenu : MenuItem DependencyProperty.Register("SelectedMenuItem", typeof(object), typeof(SingleSelectSubMenu), new PropertyMetadata(null, OnSelectedMenuItemPropertyChanged)); + + public static readonly DependencyProperty AllowNoneSelectedProperty = + DependencyProperty.Register("AllowNoneSelected", + typeof(bool), typeof(SingleSelectSubMenu), + new PropertyMetadata(false, OnAllowNoneSelectedPropertyChanged)); #endregion #region Dotnet Properties @@ -63,6 +72,16 @@ public class SingleSelectSubMenu : MenuItem get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } + + /// + /// .NET Property for AllowNoneSelected. + /// + [Bindable(false)] + public bool AllowNoneSelected + { + get { return (bool)GetValue(AllowNoneSelectedProperty); } + set { SetValue(AllowNoneSelectedProperty, value); } + } #endregion /// @@ -127,6 +146,7 @@ public class SingleSelectSubMenu : MenuItem // assign to event handler and register in dictionary newMenuItem.Checked += OnAnyItemChecked; + newMenuItem.Unchecked += OnAnyItemUnchecked; RegisteredSubItemsAndParent.Add(newMenuItem, sssm); // add to parent (which is expected to be a menu item) @@ -147,6 +167,10 @@ public class SingleSelectSubMenu : MenuItem // get associated menu items var associatedMenuitems = GetAssociatedMenuItems(menuItem); + // get parent sssm + var parentSssm = GetParentSingleSelectSubMenu(menuItem); + + parentSssm.internalUncheckingOngoing = true; foreach (var associatedItem in associatedMenuitems) { // uncheck items that are not null and not the sender item @@ -155,9 +179,46 @@ public class SingleSelectSubMenu : MenuItem associatedItem.IsChecked = false; } } + parentSssm.internalUncheckingOngoing = false; // update SelectedMenuItem for respective parent - GetParentSingleSelectSubMenu(menuItem).SelectedMenuItem = menuItem; + parentSssm.SelectedMenuItem = menuItem; + } + + /// + /// Event handler that handles registered menu items being unchecked. + /// + /// MenuItem that was checked + /// routed event args + private static void OnAnyItemUnchecked(object sender, RoutedEventArgs e) + { + // extract sender menuItem and guard null + if (sender is not MenuItem menuItem) { return; } + + // get parent sssm + var parentSssm = GetParentSingleSelectSubMenu(menuItem); + // if automated unchecking is ongoing => ignore events + if (parentSssm.internalUncheckingOngoing) { return; } + + // if unselection is not allowed => recheck + if (parentSssm.AllowNoneSelected == false) + { + menuItem.IsChecked = true; + } + } + + /// + /// Event handler that handles if the property AllowNoneSelected changed. + /// + /// sender + /// routed event args + /// + private static void OnAllowNoneSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + // extract instance and guard null + // if (d is not SingleSelectSubMenu sssm) { return; } + + // nothing to do } #region Helpers