diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBinding.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBinding.cs index 0890cda14..02acc51b5 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBinding.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBinding.cs @@ -7,6 +7,7 @@ using System; using System.ComponentModel; +using System.Diagnostics; using System.Windows; using System.Windows.Markup; using MS.Internal; @@ -60,18 +61,13 @@ public CommandBinding(ICommand command, ExecutedRoutedEventHandler executed) /// Handler associated with determining if the command can execute. public CommandBinding(ICommand command, ExecutedRoutedEventHandler executed, CanExecuteRoutedEventHandler canExecute) { - if (command == null) - { - throw new ArgumentNullException("command"); - } + _command = command ?? throw new ArgumentNullException(nameof(command)); - _command = command; - - if (executed != null) + if (executed is not null) { Executed += executed; } - if (canExecute != null) + if (canExecute is not null) { CanExecute += canExecute; } @@ -87,20 +83,8 @@ public CommandBinding(ICommand command, ExecutedRoutedEventHandler executed, Can [Localizability(LocalizationCategory.NeverLocalize)] // cannot be localized public ICommand Command { - get - { - return _command; - } - - set - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - _command = value; - } + get => _command; + set => _command = value ?? throw new ArgumentNullException(nameof(value)); } #endregion @@ -138,49 +122,46 @@ public ICommand Command /// Event arguments. internal void OnCanExecute(object sender, CanExecuteRoutedEventArgs e) { - if (!e.Handled) + if (e.Handled) return; + if (e.RoutedEvent == CommandManager.CanExecuteEvent) { - if (e.RoutedEvent == CommandManager.CanExecuteEvent) + if (CanExecute is null) { - if (CanExecute != null) - { - CanExecute(sender, e); - if (e.CanExecute) - { - e.Handled = true; - } - } - else if (!e.CanExecute) - { - // If there is an Executed handler, then the command can be executed. - if (Executed != null) - { - e.CanExecute = true; - e.Handled = true; - } - } + if (e.CanExecute) return; + // If there is an Executed handler, then the command can be executed. + if (Executed is null) return; + e.CanExecute = true; + e.Handled = true; } - else // e.RoutedEvent == CommandManager.PreviewCanExecuteEvent + else { - if (PreviewCanExecute != null) + CanExecute(sender, e); + if (e.CanExecute) { - PreviewCanExecute(sender, e); - if (e.CanExecute) - { - e.Handled = true; - } + e.Handled = true; } } } + else // e.RoutedEvent == CommandManager.PreviewCanExecuteEvent + { + if (PreviewCanExecute is null) return; + PreviewCanExecute(sender, e); + if (e.CanExecute) + { + e.Handled = true; + } + } } private bool CheckCanExecute(object sender, ExecutedRoutedEventArgs e) { - CanExecuteRoutedEventArgs canExecuteArgs = new CanExecuteRoutedEventArgs(e.Command, e.Parameter); - canExecuteArgs.RoutedEvent = CommandManager.CanExecuteEvent; + CanExecuteRoutedEventArgs canExecuteArgs = new(e.Command, e.Parameter) + { + RoutedEvent = CommandManager.CanExecuteEvent, + // Since we don't actually raise this event, we have to explicitly set the source. + Source = e.OriginalSource + }; - // Since we don't actually raise this event, we have to explicitly set the source. - canExecuteArgs.Source = e.OriginalSource; canExecuteArgs.OverrideSource(e.Source); OnCanExecute(sender, canExecuteArgs); @@ -195,30 +176,22 @@ private bool CheckCanExecute(object sender, ExecutedRoutedEventArgs e) /// Event arguments. internal void OnExecuted(object sender, ExecutedRoutedEventArgs e) { - if (!e.Handled) + if (e.Handled) return; + if (e.RoutedEvent == CommandManager.ExecutedEvent) { - if (e.RoutedEvent == CommandManager.ExecutedEvent) - { - if (Executed != null) - { - if (CheckCanExecute(sender, e)) - { - Executed(sender, e); - e.Handled = true; - } - } - } - else // e.RoutedEvent == CommandManager.PreviewExecutedEvent - { - if (PreviewExecuted != null) - { - if (CheckCanExecute(sender, e)) - { - PreviewExecuted(sender, e); - e.Handled = true; - } - } - } + if (Executed is null) return; + if (!CheckCanExecute(sender, e)) return; + Debug.Assert(Executed != null, nameof(Executed) + " != null"); + Executed(sender, e); + e.Handled = true; + } + else // e.RoutedEvent == CommandManager.PreviewExecutedEvent + { + if (PreviewExecuted is null) return; + if (!CheckCanExecute(sender, e)) return; + Debug.Assert(PreviewExecuted != null, nameof(PreviewExecuted) + " != null"); + PreviewExecuted(sender, e); + e.Handled = true; } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBindingCollection.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBindingCollection.cs index 98725d642..8adf9e4d2 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBindingCollection.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandBindingCollection.cs @@ -52,9 +52,9 @@ public CommandBindingCollection() /// CommandBinding array public CommandBindingCollection(IList commandBindings) { - if (commandBindings != null && commandBindings.Count > 0) + if (commandBindings is { Count: > 0 }) { - AddRange(commandBindings as ICollection); + AddRange(commandBindings); } } @@ -76,12 +76,9 @@ public CommandBindingCollection(IList commandBindings) /// /// commandbinding array to copy into /// start index in current list to copy - void ICollection.CopyTo(System.Array array, int index) + void ICollection.CopyTo(System.Array array, int index) { - if (_innerCBList != null) - { - ((ICollection)_innerCBList).CopyTo(array, index); - } + ((ICollection)_innerCBList)?.CopyTo(array, index); } #endregion Implementation of ICollection @@ -92,7 +89,7 @@ void ICollection.CopyTo(System.Array array, int index) /// true - if found, false - otherwise bool IList.Contains(object key) { - return this.Contains(key as CommandBinding) ; + return Contains(key as CommandBinding) ; } /// @@ -102,8 +99,7 @@ bool IList.Contains(object key) /// int IList.IndexOf(object value) { - CommandBinding commandBinding = value as CommandBinding; - return ((commandBinding != null) ? this.IndexOf(commandBinding) : -1); + return ((value is CommandBinding commandBinding) ? IndexOf(commandBinding) : -1); } /// @@ -113,7 +109,7 @@ int IList.IndexOf(object value) /// item to insert void IList.Insert(int index, object value) { - this.Insert(index, value as CommandBinding); + Insert(index, value as CommandBinding); } /// @@ -122,7 +118,7 @@ void IList.Insert(int index, object value) /// CommandBinding object to add int IList.Add(object commandBinding) { - return this.Add(commandBinding as CommandBinding); + return Add(commandBinding as CommandBinding); } /// @@ -131,7 +127,7 @@ int IList.Add(object commandBinding) /// CommandBinding object to remove void IList.Remove(object commandBinding) { - this.Remove(commandBinding as CommandBinding); + Remove(commandBinding as CommandBinding); } /// @@ -145,8 +141,7 @@ object IList.this[int index] } set { - CommandBinding commandBinding = value as CommandBinding; - if (commandBinding == null) + if (value is not CommandBinding commandBinding) throw new NotSupportedException(SR.Get(SRID.CollectionOnlyAcceptsCommandBindings)); this[index] = commandBinding; @@ -160,7 +155,7 @@ public CommandBinding this[int index] { get { - return (_innerCBList != null ? _innerCBList[index] : null); + return (_innerCBList?[index]); } set { @@ -179,8 +174,7 @@ public int Add(CommandBinding commandBinding) { if (commandBinding != null) { - if (_innerCBList == null) - _innerCBList = new System.Collections.Generic.List(1); + _innerCBList ??= new Collections.Generic.List(1); _innerCBList.Add(commandBinding); return 0; // ICollection.Add no longer returns the indice @@ -200,27 +194,23 @@ public int Add(CommandBinding commandBinding) public void AddRange(ICollection collection) { if (collection==null) - throw new ArgumentNullException("collection"); - - if (collection.Count > 0) - { - if (_innerCBList == null) - _innerCBList = new System.Collections.Generic.List(collection.Count); + throw new ArgumentNullException(nameof(collection)); + + if (collection.Count <= 0) return; + _innerCBList ??= new System.Collections.Generic.List(collection.Count); - IEnumerator collectionEnum = collection.GetEnumerator(); - while(collectionEnum.MoveNext()) + IEnumerator collectionEnum = collection.GetEnumerator(); + while(collectionEnum.MoveNext()) + { + if (collectionEnum.Current is CommandBinding cmdBinding) { - CommandBinding cmdBinding = collectionEnum.Current as CommandBinding; - if (cmdBinding != null) - { - _innerCBList.Add(cmdBinding); - } - else - { - throw new NotSupportedException(SR.Get(SRID.CollectionOnlyAcceptsCommandBindings)); - } - } - } + _innerCBList.Add(cmdBinding); + } + else + { + throw new NotSupportedException(SR.Get(SRID.CollectionOnlyAcceptsCommandBindings)); + } + } } /// @@ -232,8 +222,7 @@ public void Insert(int index, CommandBinding commandBinding) { if (commandBinding != null) { - if (_innerCBList != null) - _innerCBList.Insert(index, commandBinding); + _innerCBList?.Insert(index, commandBinding); } else { @@ -257,8 +246,7 @@ public void Remove(CommandBinding commandBinding) /// index at which the item needs to be removed public void RemoveAt(int index) { - if (_innerCBList != null) - _innerCBList.RemoveAt(index); + _innerCBList?.RemoveAt(index); } /// @@ -276,11 +264,7 @@ public bool IsSynchronized { get { - if (_innerCBList != null) - { - return ((IList)_innerCBList).IsSynchronized; - } - return false; + return _innerCBList is not null && ((IList)_innerCBList).IsSynchronized; } } @@ -310,7 +294,7 @@ public int Count { get { - return (_innerCBList != null ? _innerCBList.Count : 0); + return _innerCBList?.Count ?? 0; } } @@ -319,11 +303,9 @@ public int Count /// public void Clear() { - if (_innerCBList != null) - { - _innerCBList.Clear(); - _innerCBList = null; - } + if (_innerCBList is null) return; + _innerCBList.Clear(); + _innerCBList = null; } /// @@ -333,7 +315,7 @@ public void Clear() /// public int IndexOf(CommandBinding value) { - return ((_innerCBList != null) ? _innerCBList.IndexOf(value) : -1); + return _innerCBList?.IndexOf(value) ?? -1; } /// @@ -355,10 +337,9 @@ public bool Contains(CommandBinding commandBinding) /// /// type-safe (CommandBinding) array /// start index in current list to copy - public void CopyTo(CommandBinding[] commandBindings, int index) + public void CopyTo(CommandBinding[] commandBindings, int index) { - if (_innerCBList != null) - _innerCBList.CopyTo(commandBindings, index); + _innerCBList?.CopyTo(commandBindings, index); } #region Implementation of Enumerable @@ -385,17 +366,11 @@ internal ICommand FindMatch(object targetElement, InputEventArgs inputEventArgs) for (int i = 0; i < Count; i++) { CommandBinding commandBinding = this[i]; - RoutedCommand routedCommand = commandBinding.Command as RoutedCommand; - if (routedCommand != null) + if (commandBinding.Command is not RoutedCommand routedCommand) continue; + InputGestureCollection inputGestures = routedCommand.InputGesturesInternal; + if (inputGestures?.FindMatch(targetElement, inputEventArgs) != null) { - InputGestureCollection inputGestures = routedCommand.InputGesturesInternal; - if (inputGestures != null) - { - if (inputGestures.FindMatch(targetElement, inputEventArgs) != null) - { - return routedCommand; - } - } + return routedCommand; } } @@ -423,7 +398,7 @@ internal CommandBinding FindMatch(ICommand command, ref int index) // //------------------------------------------------------ #region Private Fields - private System.Collections.Generic.List _innerCBList; + private Collections.Generic.List _innerCBList; #endregion Private Fields } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandManager.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandManager.cs index 1434794fb..3a0454e32 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandManager.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CommandManager.cs @@ -601,64 +601,56 @@ internal static void OnCommandDevice(object sender, CommandDeviceEventArgs e) private static void FindCommandBinding(object sender, RoutedEventArgs e, ICommand command, bool execute) { // Check local command bindings - CommandBindingCollection commandBindings = null; - DependencyObject senderAsDO = sender as DependencyObject; - if (InputElement.IsUIElement(senderAsDO)) + CommandBindingCollection commandBindings = sender switch { - commandBindings = ((UIElement)senderAsDO).CommandBindingsInternal; - } - else if (InputElement.IsContentElement(senderAsDO)) - { - commandBindings = ((ContentElement)senderAsDO).CommandBindingsInternal; - } - else if (InputElement.IsUIElement3D(senderAsDO)) - { - commandBindings = ((UIElement3D)senderAsDO).CommandBindingsInternal; - } - if (commandBindings != null) + UIElement uiElement => uiElement.CommandBindingsInternal, + ContentElement contentElement => contentElement.CommandBindingsInternal, + UIElement3D uiElement3d => uiElement3d.CommandBindingsInternal, + _ => default + }; + if (commandBindings is not null) { FindCommandBinding(commandBindings, sender, e, command, execute); } + Type senderType = sender.GetType(); + // If no command binding is found, check class command bindings // First find the relevant command bindings, under the lock. // Most of the time there are no such bindings; most of the rest of // the time there is only one. Lazy-allocate with this in mind. - Tuple tuple = null; // zero or one binding - List> list = null; // more than one - + ValueTuple? tuple = default; // zero or one binding + List> list = default; // more than one + lock (_classCommandBindings.SyncRoot) { // Check from the current type to all the base types - Type classType = sender.GetType(); - while (classType != null) + Type classType = senderType; + while (classType is not null) { - CommandBindingCollection classCommandBindings = _classCommandBindings[classType] as CommandBindingCollection; - if (classCommandBindings != null) + if (_classCommandBindings[classType] is CommandBindingCollection classCommandBindings) { int index = 0; while (true) { CommandBinding commandBinding = classCommandBindings.FindMatch(command, ref index); - if (commandBinding != null) + if (commandBinding is null) { - if (tuple == null) - { - tuple = new Tuple(classType, commandBinding); - } - else - { - if (list == null) - { - list = new List>(); - list.Add(tuple); - } - list.Add(new Tuple(classType, commandBinding)); - } + break; + } + + if (tuple is null) + { + tuple = ValueTuple.Create(classType, commandBinding); } else { - break; + list ??= new List>(8) + { + // We know that tuple cannot be null here + tuple.Value + }; + list.Add(new ValueTuple(classType, commandBinding)); } } } @@ -668,37 +660,35 @@ private static void FindCommandBinding(object sender, RoutedEventArgs e, IComman // execute the bindings. This can call into user code, so it must // be done outside the lock to avoid deadlock. - if (list != null) + if (list is not null) { // more than one binding - ExecutedRoutedEventArgs exArgs = execute ? (ExecutedRoutedEventArgs)e : null; - CanExecuteRoutedEventArgs canExArgs = execute ? null : (CanExecuteRoutedEventArgs)e; - for (int i=0; i