Skip to content

Commit

Permalink
Improved MenuFlyout (#452)
Browse files Browse the repository at this point in the history
It not longer automatically closes when a single item is selected on it
  • Loading branch information
HotCakeX authored Dec 10, 2024
1 parent 9ec4f8f commit 7fa9f28
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
72 changes: 72 additions & 0 deletions AppControl Manager/CustomUIElements/MenuFlyoutV2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;

namespace AppControlManager.CustomUIElements
{
/// <summary>
/// A custom implementation of MenuFlyout that prevents the flyout from automatically closing
/// when a menu item is selected. This is achieved by tracking pointer interactions on the flyout items.
/// </summary>
internal sealed partial class MenuFlyoutV2 : MenuFlyout
{
/// <summary>
/// Initializes a new instance of the <see cref="MenuFlyoutV2"/> class.
/// Subscribes to the Opened event to attach pointer event handlers to the menu items.
/// </summary>
internal MenuFlyoutV2()
{
// Attach the handler for the Opened event to initialize event listeners for pointer interactions on menu items
Opened += MenuFlyoutV2_Opened;
}

/// <summary>
/// Property to track whether the user's pointer is currently over any menu item in the flyout.
/// </summary>
internal bool IsPointerOver { get; set; }

/// <summary>
/// Event handler for when the flyout is opened.
/// Attaches PointerEntered and PointerExited event handlers to each item in the flyout.
/// </summary>
/// <param name="sender">The source of the event (the flyout itself).</param>
/// <param name="e">The event data.</param>
private void MenuFlyoutV2_Opened(object? sender, object e)
{
// Loop through each menu item in the flyout's Items collection
foreach (MenuFlyoutItemBase menuItem in Items)
{
// Ensure existing handlers are removed to avoid multiple attachments
// (to prevent duplicate event triggers if the flyout is opened multiple times)
menuItem.PointerEntered -= MenuItem_PointerEntered;
menuItem.PointerEntered += MenuItem_PointerEntered;

menuItem.PointerExited -= MenuItem_PointerExited;
menuItem.PointerExited += MenuItem_PointerExited;
}
}

/// <summary>
/// Event handler for when the pointer enters a menu item in the flyout.
/// This sets the IsPointerOver property to true, indicating that the pointer is interacting with the menu.
/// </summary>
/// <param name="sender">The menu item that the pointer entered.</param>
/// <param name="e">The event data for the pointer interaction.</param>
private void MenuItem_PointerEntered(object sender, PointerRoutedEventArgs e)
{
// Set IsPointerOver to true, indicating the pointer is inside the flyout
IsPointerOver = true;
}

/// <summary>
/// Event handler for when the pointer exits a menu item in the flyout.
/// This sets the IsPointerOver property to false, indicating that the pointer is no longer interacting with the menu.
/// </summary>
/// <param name="sender">The menu item that the pointer exited.</param>
/// <param name="e">The event data for the pointer interaction.</param>
private void MenuItem_PointerExited(object sender, PointerRoutedEventArgs e)
{
// Set IsPointerOver to false, indicating the pointer has left the flyout
IsPointerOver = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppControlManager.Pages"
xmlns:customUI="using:AppControlManager.CustomUIElements"
xmlns:AppControlManager="using:AppControlManager"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down Expand Up @@ -44,7 +45,8 @@
</Button.Content>

<Button.Flyout>
<MenuFlyout>

<customUI:MenuFlyoutV2 Closing="MenuFlyout_Closing">

<ToggleMenuFlyoutItem Text="Base Policies" x:Name="IncludeBasePolicies" IsChecked="True">
<ToggleMenuFlyoutItem.Icon>
Expand All @@ -70,7 +72,7 @@
</ToggleMenuFlyoutItem.Icon>
</ToggleMenuFlyoutItem>

</MenuFlyout>
</customUI:MenuFlyoutV2>
</Button.Flyout>
</Button>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using AppControlManager.Logging;
using AppControlManager.SiPolicy;
using CommunityToolkit.WinUI.UI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
Expand All @@ -14,6 +13,7 @@

namespace AppControlManager.Pages
{

public sealed partial class ViewCurrentPolicies : Page
{
// To store the policies displayed on the DataGrid
Expand Down Expand Up @@ -559,5 +559,22 @@ private static string ConvertRowToText(CiPolicyInfo row)
}


#pragma warning disable CA1822

/// <summary>
/// Event handler to prevent the MenuFlyout to automatically close immediately after selecting a checkbox or any button in it
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void MenuFlyout_Closing(FlyoutBase sender, FlyoutBaseClosingEventArgs args)
{
if (sender is CustomUIElements.MenuFlyoutV2 { IsPointerOver: true })
{
args.Cancel = true;
}
}

#pragma warning restore CA1822

}
}

0 comments on commit 7fa9f28

Please sign in to comment.