CmdPal: Refactoring ContextMenu adding separators, IsCritical styling, and right-click context menus for list items (#40189)

Refactored ContextMenu into it's own control to allow displaying in
CommandBar and in response to right click on list items.

- Adds "critical" styling to context menu items flagged as `IsCritical`.
This will use the theme to style with correct color.
- Added `SeparatorContextItem` and modified `MoreCommands` to allow for
both `CommandContextItem`s and `SeparatorContextItem`s.
- Right clicking a list item with a context menu will open the context
menu at the position of the click and position the filter box at the top
of the context menu.


![image](https://github.com/user-attachments/assets/3bef6b04-28bb-4a17-b731-d9ed20c0566f)


![image](https://github.com/user-attachments/assets/37ed497c-6d98-4f04-8114-d9952127ca2e)


This PR covers:

- closes #38308
- closes #39211
- closes #38307
- closes #38261
This commit is contained in:
Michael Jolley
2025-07-09 14:53:47 -05:00
committed by GitHub
parent 18b61ce9b7
commit 100fca4468
23 changed files with 984 additions and 477 deletions

View File

@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
/// <summary>
/// Used to announce that a context menu should close
/// </summary>
public record CloseContextMenuMessage
{
}

View File

@@ -2,11 +2,21 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls.Primitives;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
/// <summary>
/// Used to perform a list item's secondary command when the user presses ctrl+enter in the search box
/// Used to announce the context menu should open
/// </summary>
public record OpenContextMenuMessage
public record OpenContextMenuMessage(FrameworkElement? Element, FlyoutPlacementMode? FlyoutPlacementMode, Point? Point, ContextMenuFilterLocation ContextMenuFilterLocation)
{
}
public enum ContextMenuFilterLocation
{
Top,
Bottom,
}

View File

@@ -16,11 +16,11 @@ public record UpdateCommandBarMessage(ICommandBarContext? ViewModel)
public interface IContextMenuContext : INotifyPropertyChanged
{
public IEnumerable<CommandContextItemViewModel> MoreCommands { get; }
public IEnumerable<IContextItemViewModel> MoreCommands { get; }
public bool HasMoreCommands { get; }
public List<CommandContextItemViewModel> AllCommands { get; }
public List<IContextItemViewModel> AllCommands { get; }
/// <summary>
/// Generates a mapping of key -> command item for this particular item's
@@ -33,6 +33,7 @@ public interface IContextMenuContext : INotifyPropertyChanged
public Dictionary<KeyChord, CommandContextItemViewModel> Keybindings()
{
return MoreCommands
.OfType<CommandContextItemViewModel>()
.Where(c => c.HasRequestedShortcut)
.ToDictionary(
c => c.RequestedShortcut ?? new KeyChord(0, 0, 0),