Merge pull request #701 from irihitech/navmenu

NavMenu: SelectionChanging Event
This commit is contained in:
Zhang Dian
2025-07-11 14:48:33 +08:00
committed by GitHub
8 changed files with 256 additions and 0 deletions

View File

@@ -189,6 +189,16 @@ public class NavMenu : ItemsControl, ICustomKeyboardNavigation
add => AddHandler(SelectionChangedEvent, value);
remove => RemoveHandler(SelectionChangedEvent, value);
}
public static readonly RoutedEvent<SelectionChangingEventArgs> SelectionChangingEvent =
RoutedEvent.Register<NavMenu, SelectionChangingEventArgs>(nameof(SelectionChanging), RoutingStrategies.Bubble);
public event EventHandler<SelectionChangingEventArgs> SelectionChanging
{
add => AddHandler(SelectionChangingEvent, value);
remove => RemoveHandler(SelectionChangingEvent, value);
}
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
{
@@ -486,4 +496,28 @@ public class NavMenu : ItemsControl, ICustomKeyboardNavigation
return null;
}
internal bool CanChangeSelection(NavMenuItem item)
{
object? newSelection = null;
if (item.DataContext is not null && item.DataContext != DataContext)
newSelection = item.DataContext;
else
newSelection = item;
var args = new SelectionChangingEventArgs(
SelectionChangingEvent,
new[] { SelectedItem },
new[] { newSelection })
{
Source = this,
};
RaiseEvent(args);
var result = args.CanSelect;
if (result == false)
{
var container = GetContainerForItem(SelectedItem);
container?.Focus(NavigationMethod.Directional);
}
return result;
}
}

View File

@@ -381,6 +381,10 @@ public class NavMenuItem : HeaderedItemsControl
internal void SelectItem(NavMenuItem item)
{
if (item == this && RootMenu?.CanChangeSelection(item) != true)
{
return;
}
SetCurrentValue(IsSelectedProperty, item == this);
SetCurrentValue(IsHighlightedProperty, true);

View File

@@ -0,0 +1,24 @@
using System.Collections;
using Avalonia.Interactivity;
namespace Ursa.Controls;
public class SelectionChangingEventArgs: RoutedEventArgs
{
/// <summary>Gets the items that were added to the selection.</summary>
public IList NewItems { get; }
/// <summary>Gets the items that were removed from the selection.</summary>
public IList OldItems { get; }
/// <summary>
/// Gets or sets a value indicating whether the selection can be changed. If set to <c>false</c>, the selection will not change.
/// </summary>
public bool CanSelect { get; set; } = true;
public SelectionChangingEventArgs(RoutedEvent routedEvent, IList oldItems, IList newItems): base(routedEvent)
{
OldItems = oldItems;
NewItems = newItems;
}
}