Fixed CheckBox issue

This commit is contained in:
Tig
2024-12-05 15:04:23 -07:00
parent 53d7449c85
commit 65cf641685
13 changed files with 127 additions and 151 deletions

View File

@@ -10,11 +10,18 @@ public record struct MouseBinding
{
/// <summary>Initializes a new instance.</summary>
/// <param name="commands">The commands this mouse binding will invoke.</param>
public MouseBinding (Command [] commands)
/// <param name="mouseEventArgs">The mouse event arguments, to be passed as context.</param>
public MouseBinding (Command [] commands, MouseEventArgs? mouseEventArgs)
{
Commands = commands;
MouseEventArgs = mouseEventArgs;
}
/// <summary>The commands this key binding will invoke.</summary>
public Command [] Commands { get; set; }
/// <summary>
/// The mouse event arguments.
/// </summary>
public MouseEventArgs? MouseEventArgs { get; set; }
}

View File

@@ -15,21 +15,20 @@ public class MouseBindings
public MouseBindings () { }
/// <summary>Adds a <see cref="MouseBinding"/> to the collection.</summary>
/// <param name="mouseEvent"></param>
/// <param name="mouseEventArgs"></param>
/// <param name="binding"></param>
public void Add (MouseEventArgs mouseEvent, MouseBinding binding)
public void Add (MouseEventArgs mouseEventArgs, MouseBinding binding)
{
if (TryGet (mouseEvent, out MouseBinding _))
if (TryGet (mouseEventArgs, out MouseBinding _))
{
throw new InvalidOperationException (@$"A binding for {mouseEvent} exists ({binding}).");
throw new InvalidOperationException (@$"A binding for {mouseEventArgs} exists ({binding}).");
}
// IMPORTANT: Add a COPY of the key. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy
// IMPORTANT: Add a COPY of the mouseEventArgs. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy
// IMPORTANT: update the memory referenced by the key, and Dictionary uses caching for performance, and thus
// IMPORTANT: Apply will update the Dictionary with the new key, but the old key will still be in the dictionary.
// IMPORTANT: Apply will update the Dictionary with the new mouseEventArgs, but the old mouseEventArgs will still be in the dictionary.
// IMPORTANT: See the ConfigurationManager.Illustrate_DeepMemberWiseCopy_Breaks_Dictionary test for details.
Bindings.Add (mouseEvent, binding);
Bindings.Add (mouseEventArgs, binding);
}
/// <summary>
@@ -43,15 +42,16 @@ public class MouseBindings
/// Commands are only ever applied to the current <see cref="View"/> (i.e. this feature cannot be used to switch
/// focus to another view and perform multiple commands there).
/// </remarks>
/// <param name="mouseEvents">The mouse flags to check.</param>
/// <param name="mouseEventArgs">The mouse flags to check.</param>
/// <param name="commands">
/// The command to invoked on the <see cref="View"/> when <paramref name="mouseEvents"/> is received. When
/// multiple commands are provided,they will be applied in sequence. The bound <paramref name="mouseEvents"/> event will be
/// The command to invoked on the <see cref="View"/> when <paramref name="mouseEventArgs"/> is received. When
/// multiple commands are provided,they will be applied in sequence. The bound <paramref name="mouseEventArgs"/> event
/// will be
/// consumed if any took effect.
/// </param>
public void Add (MouseEventArgs mouseEvents, params Command [] commands)
public void Add (MouseEventArgs mouseEventArgs, params Command [] commands)
{
if (mouseEvents.Flags == MouseFlags.None)
if (mouseEventArgs.Flags == MouseFlags.None)
{
throw new ArgumentException (@"Invalid MouseFlag", nameof (commands));
}
@@ -61,12 +61,12 @@ public class MouseBindings
throw new ArgumentException (@"At least one command must be specified", nameof (commands));
}
if (TryGet (mouseEvents, out MouseBinding binding))
if (TryGet (mouseEventArgs, out MouseBinding binding))
{
throw new InvalidOperationException (@$"A binding for {mouseEvents} exists ({binding}).");
throw new InvalidOperationException (@$"A binding for {mouseEventArgs} exists ({binding}).");
}
Add (mouseEvents, new MouseBinding (commands));
Add (mouseEventArgs, new MouseBinding (commands, mouseEventArgs));
}
// TODO: Add a dictionary comparer that ignores Scope
@@ -74,15 +74,6 @@ public class MouseBindings
/// <summary>The collection of <see cref="MouseBinding"/> objects.</summary>
public Dictionary<MouseEventArgs, MouseBinding> Bindings { get; } = new ();
/// <summary>
/// Gets the <see cref="MouseEventArgs"/> that are bound.
/// </summary>
/// <returns></returns>
public IEnumerable<MouseEventArgs> GetBoundMouseEventArgs ()
{
return Bindings.Keys;
}
/// <summary>Removes all <see cref="MouseBinding"/> objects from the collection.</summary>
public void Clear () { Bindings.Clear (); }
@@ -94,8 +85,8 @@ public class MouseBindings
public void Clear (params Command [] command)
{
KeyValuePair<MouseEventArgs, MouseBinding> [] kvps = Bindings
.Where (kvp => kvp.Value.Commands.SequenceEqual (command))
.ToArray ();
.Where (kvp => kvp.Value.Commands.SequenceEqual (command))
.ToArray ();
foreach (KeyValuePair<MouseEventArgs, MouseBinding> kvp in kvps)
{
@@ -104,27 +95,48 @@ public class MouseBindings
}
/// <summary>Gets the <see cref="MouseBinding"/> for the specified combination of <see cref="MouseEventArgs"/>.</summary>
/// <param name="mouseEvents"></param>
/// <param name="mouseEventArgs"></param>
/// <returns></returns>
public MouseBinding Get (MouseEventArgs mouseEvents)
public MouseBinding Get (MouseEventArgs mouseEventArgs)
{
if (TryGet (mouseEvents, out MouseBinding binding))
if (TryGet (mouseEventArgs, out MouseBinding binding))
{
return binding;
}
throw new InvalidOperationException ($"{mouseEvents} is not bound.");
throw new InvalidOperationException ($"{mouseEventArgs} is not bound.");
}
/// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="mouseEvents"/> if it exists.</summary>
/// <param name="mouseEvents">The key to check.</param>
/// <summary>
/// Gets combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
/// <paramref name="commands"/>.
/// </summary>
/// <param name="commands">The set of commands to search.</param>
/// <returns>
/// The array of <see cref="Command"/>s if <paramref name="mouseEvents"/> is bound. An empty <see cref="Command"/> array
/// The combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
/// <paramref name="commands"/>. An empty list if the set of caommands was not found.
/// </returns>
public IEnumerable<MouseEventArgs> GetAllMouseEventArgsFromCommands (params Command [] commands)
{
return Bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
}
/// <summary>
/// Gets the <see cref="MouseEventArgs"/> that are bound.
/// </summary>
/// <returns></returns>
public IEnumerable<MouseEventArgs> GetBoundMouseEventArgs () { return Bindings.Keys; }
/// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="mouseEventArgs"/> if it exists.</summary>
/// <param name="mouseEventArgs">The key to check.</param>
/// <returns>
/// The array of <see cref="Command"/>s if <paramref name="mouseEventArgs"/> is bound. An empty <see cref="Command"/>
/// array
/// if not.
/// </returns>
public Command [] GetCommands (MouseEventArgs mouseEvents)
public Command [] GetCommands (MouseEventArgs mouseEventArgs)
{
if (TryGet (mouseEvents, out MouseBinding bindings))
if (TryGet (mouseEventArgs, out MouseBinding bindings))
{
return bindings.Commands;
}
@@ -132,32 +144,30 @@ public class MouseBindings
return [];
}
/// <summary>Gets the first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by <paramref name="commands"/>.</summary>
/// <summary>
/// Gets the first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
/// <paramref name="commands"/>.
/// </summary>
/// <param name="commands">The set of commands to search.</param>
/// <returns>The first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by <paramref name="commands"/>. <see langword="null"/> if the set of caommands was not found.</returns>
/// <returns>
/// The first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
/// <paramref name="commands"/>. <see langword="null"/> if the set of caommands was not found.
/// </returns>
public MouseEventArgs? GetMouseEventArgsFromCommands (params Command [] commands)
{
return Bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key;
}
/// <summary>Gets combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by <paramref name="commands"/>.</summary>
/// <param name="commands">The set of commands to search.</param>
/// <returns>The combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by <paramref name="commands"/>. An empty list if the set of caommands was not found.</returns>
public IEnumerable<MouseEventArgs> GetAllMouseEventArgsFromCommands (params Command [] commands)
{
return Bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
}
/// <summary>Removes a <see cref="MouseBinding"/> from the collection.</summary>
/// <param name="mouseEvents"></param>
public void Remove (MouseEventArgs mouseEvents)
/// <param name="mouseEventArgs"></param>
public void Remove (MouseEventArgs mouseEventArgs)
{
if (!TryGet (mouseEvents, out MouseBinding _))
if (!TryGet (mouseEventArgs, out MouseBinding _))
{
return;
}
Bindings.Remove (mouseEvents);
Bindings.Remove (mouseEventArgs);
}
/// <summary>Replaces the commands already bound to a combination of <see cref="MouseEventArgs"/>.</summary>
@@ -166,24 +176,27 @@ public class MouseBindings
/// If the combination of <see cref="MouseEventArgs"/> is not already bound, it will be added.
/// </para>
/// </remarks>
/// <param name="mouseEvents">The combination of <see cref="MouseEventArgs"/> bound to the command to be replaced.</param>
/// <param name="mouseEventArgs">The combination of <see cref="MouseEventArgs"/> bound to the command to be replaced.</param>
/// <param name="commands">The set of commands to replace the old ones with.</param>
public void ReplaceCommands (MouseEventArgs mouseEvents, params Command [] commands)
public void ReplaceCommands (MouseEventArgs mouseEventArgs, params Command [] commands)
{
if (TryGet (mouseEvents, out MouseBinding binding))
if (TryGet (mouseEventArgs, out MouseBinding binding))
{
binding.Commands = commands;
}
else
{
Add (mouseEvents, commands);
Add (mouseEventArgs, commands);
}
}
/// <summary>Replaces a <see cref="MouseEventArgs"/> combination already bound to a set of <see cref="Command"/>s.</summary>
/// <remarks></remarks>
/// <param name="oldMouseEventArgs">The <see cref="MouseEventArgs"/> to be replaced.</param>
/// <param name="newMouseEventArgs">The new <see cref="MouseEventArgs"/> to be used. If <see cref="Key.Empty"/> no action will be taken.</param>
/// <param name="newMouseEventArgs">
/// The new <see cref="MouseEventArgs"/> to be used. If <see cref="Key.Empty"/> no action
/// will be taken.
/// </param>
public void ReplaceKey (MouseEventArgs oldMouseEventArgs, MouseEventArgs newMouseEventArgs)
{
if (!TryGet (oldMouseEventArgs, out MouseBinding _))
@@ -198,17 +211,16 @@ public class MouseBindings
/// <summary>Gets the commands bound with the specified <see cref="MouseEventArgs"/>.</summary>
/// <remarks></remarks>
/// <param name="mouseEvents">The key to check.</param>
/// <param name="mouseEventArgs">The key to check.</param>
/// <param name="binding">
/// When this method returns, contains the commands bound with the specified mouse flags, if the mouse flags are
/// found; otherwise, null. This parameter is passed uninitialized.
/// </param>
/// <returns><see langword="true"/> if the mouse flags are bound; otherwise <see langword="false"/>.</returns>
public bool TryGet (MouseEventArgs mouseEvents, out MouseBinding binding)
public bool TryGet (MouseEventArgs mouseEventArgs, out MouseBinding binding)
{
binding = new ([], mouseEventArgs);
binding = new ([]);
return Bindings.TryGetValue (mouseEvents, out binding);
return Bindings.TryGetValue (mouseEventArgs, out binding);
}
}

View File

@@ -360,7 +360,7 @@ public partial class View // Mouse APIs
// Always invoke Select command on MouseClick
// By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...).
args.Handled = InvokeCommand<KeyBinding> (Command.Select, new ([Command.Select], KeyBindingScope.Focused, null, args)) == true;
args.Handled = InvokeCommand<MouseBinding> (Command.Select, new ([Command.Select], args)) == true;
return args.Handled;
}
@@ -666,15 +666,15 @@ public partial class View // Mouse APIs
if (start is not Adornment)
{
if (start.Margin is {} && start.Margin.Contains (currentLocation))
if (start.Margin is { } && start.Margin.Contains (currentLocation))
{
found = start.Margin;
}
else if (start.Border is {} && start.Border.Contains (currentLocation))
else if (start.Border is { } && start.Border.Contains (currentLocation))
{
found = start.Border;
}
else if (start.Padding is { } && start.Padding.Contains(currentLocation))
else if (start.Padding is { } && start.Padding.Contains (currentLocation))
{
found = start.Padding;
}

View File

@@ -72,18 +72,14 @@ public class Button : View, IDesignable
private bool? HandleHotKeyCommand (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
bool cachedIsDefault = IsDefault; // Supports "Swap Default" in Buttons scenario where IsDefault changes
if (RaiseSelecting (ctx) is true)
if (RaiseSelecting (commandContext) is true)
{
return true;
}
bool? handled = RaiseAccepting (ctx);
bool? handled = RaiseAccepting (commandContext);
if (handled == true)
{
@@ -97,7 +93,7 @@ public class Button : View, IDesignable
// If Accept was not handled...
if (cachedIsDefault && SuperView is { })
{
return SuperView.InvokeCommand<KeyBinding> (Command.Accept, ctx.Binding);
return SuperView.InvokeCommand (Command.Accept);
}
return false;
@@ -137,7 +133,7 @@ public class Button : View, IDesignable
}
// TODO: With https://github.com/gui-cs/Terminal.Gui/issues/3778 we won't have to pass data:
e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new KeyBinding([Command.HotKey], KeyBindingScope.HotKey, this, null)) == true;
e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new KeyBinding ([Command.HotKey], KeyBindingScope.HotKey, this, null)) == true;
}
private void Button_TitleChanged (object sender, EventArgs<string> e)

View File

@@ -24,7 +24,14 @@ public class CheckBox : View
AddCommand (Command.Select, AdvanceAndSelect);
// Hotkey - Advance state and raise Select event - DO NOT raise Accept
AddCommand (Command.HotKey, AdvanceAndSelect);
AddCommand (Command.HotKey, ctx =>
{
if (RaiseHandlingHotKey () is true)
{
return true;
}
return AdvanceAndSelect (ctx);
});
// Accept (Enter key) - Raise Accept event - DO NOT advance state
AddCommand (Command.Accept, RaiseAccepting);
@@ -34,13 +41,8 @@ public class CheckBox : View
HighlightStyle = DefaultHighlightStyle;
}
private bool? AdvanceAndSelect (ICommandContext commandContext)
private bool? AdvanceAndSelect (ICommandContext? commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
bool? cancelled = AdvanceCheckState ();
if (cancelled is true)
@@ -48,12 +50,12 @@ public class CheckBox : View
return true;
}
if (RaiseSelecting (ctx) is true)
if (RaiseSelecting (commandContext) is true)
{
return true;
}
return ctx.Command == Command.HotKey ? cancelled : cancelled is false;
return commandContext?.Command == Command.HotKey ? cancelled : cancelled is false;
}
private void Checkbox_TitleChanged (object? sender, EventArgs<string> e)

View File

@@ -69,11 +69,7 @@ public class ColorPicker16 : View
/// <returns></returns>
private bool MoveDown (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (RaiseSelecting (ctx) == true)
if (RaiseSelecting (commandContext) == true)
{
return true;
}
@@ -89,11 +85,7 @@ public class ColorPicker16 : View
/// <returns></returns>
private bool MoveLeft (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (RaiseSelecting (ctx) == true)
if (RaiseSelecting (commandContext) == true)
{
return true;
}
@@ -110,11 +102,7 @@ public class ColorPicker16 : View
/// <returns></returns>
private bool MoveRight (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (RaiseSelecting (ctx) == true)
if (RaiseSelecting (commandContext) == true)
{
return true;
}
@@ -130,11 +118,7 @@ public class ColorPicker16 : View
/// <returns></returns>
private bool MoveUp (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (RaiseSelecting (ctx) == true)
if (RaiseSelecting (commandContext) == true)
{
return true;
}
@@ -206,9 +190,9 @@ public class ColorPicker16 : View
{
bool set = false;
if (ctx is CommandContext<MouseEventArgs> { Binding: { } } mouseCommandContext)
if (ctx is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } } mouseCommandContext)
{
Cursor = new (mouseCommandContext.Binding.Position.X / _boxWidth, mouseCommandContext.Binding.Position.Y / _boxHeight);
Cursor = new (mouseCommandContext.Binding.MouseEventArgs.Position.X / _boxWidth, mouseCommandContext.Binding.MouseEventArgs.Position.Y / _boxHeight);
set = true;
}
return RaiseAccepting (ctx) == true || set;

View File

@@ -401,10 +401,6 @@ public class ComboBox : View, IDesignable
private bool ActivateSelected (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (HasItems ())
{
if (SelectText ())
@@ -412,7 +408,7 @@ public class ComboBox : View, IDesignable
return false;
}
return RaiseAccepting (ctx) == true;
return RaiseAccepting (commandContext) == true;
}
return false;

View File

@@ -62,10 +62,6 @@ public class Label : View, IDesignable
private bool? InvokeHotKeyOnNext (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
if (RaiseHandlingHotKey () == true)
{
return true;
@@ -82,7 +78,8 @@ public class Label : View, IDesignable
if (me != -1 && me < SuperView?.Subviews.Count - 1)
{
return SuperView?.Subviews [me + 1].InvokeCommand<KeyBinding> (Command.HotKey, ctx.Binding) == true;
return SuperView?.Subviews [me + 1].InvokeCommand (Command.HotKey) == true;
}
return false;

View File

@@ -302,20 +302,17 @@ public class Shortcut : View, IOrientation, IDesignable
private bool? DispatchCommand (ICommandContext? commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
CommandContext<KeyBinding>? keyCommandContext = commandContext is CommandContext<KeyBinding> ? (CommandContext<KeyBinding>)commandContext : default;
if (ctx.Binding.Data != this)
if (keyCommandContext?.Binding.Data != this)
{
// Invoke Select on the command view to cause it to change state if it wants to
// If this causes CommandView to raise Accept, we eat it
ctx.Binding = ctx.Binding with { Data = this };
CommandView.InvokeCommand (Command.Select, ctx);
keyCommandContext = keyCommandContext!.Value with { Binding = keyCommandContext.Value.Binding with { Data = this } };
CommandView.InvokeCommand (Command.Select, keyCommandContext);
}
if (RaiseSelecting (ctx) is true)
if (RaiseSelecting (keyCommandContext) is true)
{
return true;
}
@@ -325,14 +322,14 @@ public class Shortcut : View, IOrientation, IDesignable
var cancel = false;
cancel = RaiseAccepting (ctx) is true;
cancel = RaiseAccepting (commandContext) is true;
if (cancel)
{
return true;
}
if (ctx.Command != Command.Accept)
if (commandContext?.Command != Command.Accept)
{
// return false;
}
@@ -347,7 +344,7 @@ public class Shortcut : View, IOrientation, IDesignable
if (_targetView is { })
{
_targetView.InvokeCommand (Command, ctx);
_targetView.InvokeCommand (Command, commandContext);
}
return cancel;
@@ -498,7 +495,8 @@ public class Shortcut : View, IOrientation, IDesignable
void CommandViewOnSelecting (object? sender, CommandEventArgs e)
{
if (e.Context is CommandContext<KeyBinding> keyCommandContext && keyCommandContext.Binding.Data != this)
if ((e.Context is CommandContext<KeyBinding> keyCommandContext && keyCommandContext.Binding.Data != this) ||
e.Context is CommandContext<MouseBinding>)
{
// Forward command to ourselves
InvokeCommand<KeyBinding> (Command.Select, new ([Command.Select], KeyBindingScope.Focused, null, this));

View File

@@ -850,7 +850,7 @@ public class Slider<T> : View, IOrientation
if (IsInitialized)
{
normalAttr = GetNormalColor();
normalAttr = GetNormalColor ();
setAttr = Style.SetChar.Attribute ?? GetHotNormalColor ();
}
@@ -1787,13 +1787,9 @@ public class Slider<T> : View, IOrientation
internal bool Accept (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
SetFocusedOption ();
return RaiseAccepting (ctx) == true;
return RaiseAccepting (commandContext) == true;
}
internal bool MovePlus ()

View File

@@ -3719,7 +3719,7 @@ public class TextView : View
col = _wrapManager.GetModelColFromWrappedLines (CurrentRow, CurrentColumn);
}
UnwrappedCursorPosition?.Invoke (this, new Point (row.Value, col.Value));
UnwrappedCursorPosition?.Invoke (this, new Point (col.Value, row.Value));
}
/// <summary>Paste the clipboard contents into the current selected position.</summary>
@@ -6143,12 +6143,8 @@ public class TextView : View
Paste ();
}
private bool ProcessEnterKey (ICommandContext commandContext)
private bool ProcessEnterKey (ICommandContext? commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
ResetColumnTrack ();
if (_isReadOnly)
@@ -6160,7 +6156,7 @@ public class TextView : View
{
// By Default pressing ENTER should be ignored (OnAccept will return false or null). Only cancel if the
// event was fired and set Cancel = true.
return RaiseAccepting (ctx) is null or false;
return RaiseAccepting (commandContext) is null or false;
}
SetWrapModel ();

View File

@@ -464,12 +464,8 @@ public class TreeView<T> : View, ITreeView where T : class
/// <returns><see langword="true"/> if <see cref="ObjectActivated"/> was fired.</returns>
public bool? ActivateSelectedObjectIfAny (ICommandContext commandContext)
{
if (commandContext is not CommandContext<KeyBinding> ctx)
{
return false;
}
// By default, Command.Accept calls OnAccept, so we need to call it here to ensure that the event is fired.
if (RaiseAccepting (ctx) == true)
if (RaiseAccepting (commandContext) == true)
{
return true;
}

View File

@@ -188,25 +188,21 @@ public class AllViewsTests (ITestOutputHelper output) : TestsAllViews
view.HotKey = Key.T;
}
var selectingCount = 0;
view.Selecting += (s, e) => selectingCount++;
var acceptedCount = 0;
view.Accepting += (s, e) =>
{
acceptedCount++;
};
var hotkeyHandledCount = 0;
var handlingHotKeyCount = 0;
view.HandlingHotKey += (s, e) =>
{
hotkeyHandledCount++;
handlingHotKeyCount++;
};
if (view.InvokeCommand (Command.HotKey) == true)
{
Assert.Equal (1, hotkeyHandledCount);
Assert.Equal (0, selectingCount);
Assert.Equal (1, handlingHotKeyCount);
Assert.Equal (0, acceptedCount);
}
}