From 287aa3131bcf520b5bea62b7da39e7ad5994f10c Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Sun, 5 May 2024 09:42:21 +0100 Subject: [PATCH] WIP --- .../AttachedEventTriggerBehaviour.cs | 34 ++++++++ Toolkit.UI.Avalonia/ItemInvokedEventArgs.cs | 9 ++ .../NavigationViewItemExtension.cs | 68 +++++++++++++++ .../NavigationViewItemInvokedBehaviour.cs | 86 ------------------- 4 files changed, 111 insertions(+), 86 deletions(-) create mode 100644 Toolkit.UI.Avalonia/AttachedEventTriggerBehaviour.cs create mode 100644 Toolkit.UI.Avalonia/ItemInvokedEventArgs.cs create mode 100644 Toolkit.UI.Avalonia/NavigationViewItemExtension.cs delete mode 100644 Toolkit.UI.Avalonia/NavigationViewItemInvokedBehaviour.cs diff --git a/Toolkit.UI.Avalonia/AttachedEventTriggerBehaviour.cs b/Toolkit.UI.Avalonia/AttachedEventTriggerBehaviour.cs new file mode 100644 index 0000000..8c47319 --- /dev/null +++ b/Toolkit.UI.Avalonia/AttachedEventTriggerBehaviour.cs @@ -0,0 +1,34 @@ +using Avalonia; +using Avalonia.Interactivity; +using Avalonia.Xaml.Interactivity; + +namespace Toolkit.UI.Avalonia; + +public class AttachedEventTriggerBehaviour : Trigger +{ + public static readonly StyledProperty RoutedEventProperty = + AvaloniaProperty.Register(nameof(RoutedEvent)); + + public RoutedEvent RoutedEvent + { + get => GetValue(RoutedEventProperty); + set => SetValue(RoutedEventProperty, value); + } + + protected override void OnAttached() + { + if (RoutedEvent is not null) + { + if (AssociatedObject is Interactive interactive) + { + interactive.AddHandler(RoutedEvent, (object sender, RoutedEventArgs args) => { + + Interaction.ExecuteActions(AssociatedObject, Actions, null); + + }); + } + } + + base.OnAttached(); + } +} diff --git a/Toolkit.UI.Avalonia/ItemInvokedEventArgs.cs b/Toolkit.UI.Avalonia/ItemInvokedEventArgs.cs new file mode 100644 index 0000000..d15588c --- /dev/null +++ b/Toolkit.UI.Avalonia/ItemInvokedEventArgs.cs @@ -0,0 +1,9 @@ +using Avalonia.Interactivity; + +namespace Toolkit.UI.Avalonia; + +public class ItemInvokedEventArgs : + RoutedEventArgs +{ + +} diff --git a/Toolkit.UI.Avalonia/NavigationViewItemExtension.cs b/Toolkit.UI.Avalonia/NavigationViewItemExtension.cs new file mode 100644 index 0000000..125b4f6 --- /dev/null +++ b/Toolkit.UI.Avalonia/NavigationViewItemExtension.cs @@ -0,0 +1,68 @@ +using Avalonia; +using Avalonia.Interactivity; +using Avalonia.LogicalTree; +using Toolkit.UI.Controls.Avalonia; + +namespace Toolkit.UI.Avalonia; + +public class NavigationViewItemExtension +{ + public static readonly AttachedProperty IsItemClickEnabledProperty = + AvaloniaProperty.RegisterAttached("IsItemClickEnabled", + typeof(NavigationViewItemExtension), false); + + public static readonly RoutedEvent ItemClickEvent = + RoutedEvent.Register("ItemClick", + RoutingStrategies.Bubble, typeof(NavigationViewItemExtension)); + + static NavigationViewItemExtension() + { + IsItemClickEnabledProperty.Changed.AddClassHandler(OnIsItemClickEnabledPropertyChanged); + } + + private static void OnIsItemClickEnabledPropertyChanged(NavigationViewItem sender, + AvaloniaPropertyChangedEventArgs args) + { + bool TrySetupNavigationView() + { + if (sender.GetLogicalAncestors().OfType().FirstOrDefault() is NavigationView navigationView) + { + void OnItemInvoked(object? _, FluentAvalonia.UI.Controls.NavigationViewItemInvokedEventArgs args) + { + if (args.InvokedItemContainer == sender) + { + sender.RaiseEvent(new ItemInvokedEventArgs { RoutedEvent = ItemClickEvent }); + } + } + + navigationView.ItemInvoked += OnItemInvoked; + return true; + } + + return false; + } + + if (!TrySetupNavigationView()) + { + void OnAttachedToVisualTree(object? _, VisualTreeAttachmentEventArgs __) + { + sender.AttachedToVisualTree -= OnAttachedToVisualTree; + TrySetupNavigationView(); + } + + sender.AttachedToVisualTree += OnAttachedToVisualTree; + } + } + + public static bool GetIsItemClickEnabled(NavigationViewItem element) => + element.GetValue(IsItemClickEnabledProperty); + + public static void SetIsItemClickEnabled(NavigationViewItem element, bool value) => + element.SetValue(IsItemClickEnabledProperty, value); + + public static void AddItemClickHandler(NavigationViewItem element, EventHandler handler) => + element.AddHandler(ItemClickEvent, handler); + + public static void RemoveItemClickHandler(NavigationViewItem element, EventHandler handler) => + element.RemoveHandler(ItemClickEvent, handler); +} diff --git a/Toolkit.UI.Avalonia/NavigationViewItemInvokedBehaviour.cs b/Toolkit.UI.Avalonia/NavigationViewItemInvokedBehaviour.cs deleted file mode 100644 index 55e6304..0000000 --- a/Toolkit.UI.Avalonia/NavigationViewItemInvokedBehaviour.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Avalonia; -using Avalonia.VisualTree; -using Avalonia.Xaml.Interactivity; -using FluentAvalonia.Core; -using System.Collections; -using Toolkit.UI.Controls.Avalonia; -using ISelectable = Toolkit.Foundation.ISelectable; - -namespace Toolkit.UI.Avalonia; - -public class NavigationViewItemInvokedBehaviour : Trigger -{ - public static readonly StyledProperty SelectsChildOnInvokedProperty = - AvaloniaProperty.Register(nameof(SelectsChildOnInvoked)); - - private NavigationView? navigationView; - - public event TypedEventHandler? Invoked; - - public bool SelectsChildOnInvoked - { - get => GetValue(SelectsChildOnInvokedProperty); - set => SetValue(SelectsChildOnInvokedProperty, value); - } - - protected override void OnAttached() - { - if (AssociatedObject is NavigationViewItem navigationViewItem) - { - navigationViewItem.AttachedToVisualTree += OnAttachedToVisualTree; - } - - base.OnAttached(); - } - - protected override void OnDetachedFromVisualTree() - { - if (navigationView is not null) - { - navigationView.ItemInvoked -= OnItemInvoked; - } - - base.OnDetachedFromVisualTree(); - } - - private void OnAttachedToVisualTree(object? sender, - VisualTreeAttachmentEventArgs args) - { - if (AssociatedObject is NavigationViewItem navigationViewItem) - { - navigationViewItem.AttachedToVisualTree -= OnAttachedToVisualTree; - SetupNavigationView(); - } - } - - private void OnItemInvoked(object? sender, - FluentAvalonia.UI.Controls.NavigationViewItemInvokedEventArgs args) - { - if (AssociatedObject is NavigationViewItem navigationViewItem) - { - if (args.InvokedItemContainer == AssociatedObject) - { - Interaction.ExecuteActions(AssociatedObject, Actions, null); - if (!navigationViewItem.IsChildSelected && navigationViewItem.MenuItemsSource is IList collection) - { - if (collection is { Count: > 0 } && collection[0] is ISelectable selectable) - { - selectable.Selected = true; - } - } - } - } - } - - private void SetupNavigationView() - { - if (AssociatedObject is NavigationViewItem navigationViewItem) - { - if (navigationViewItem.GetVisualAncestors().OfType().FirstOrDefault() is NavigationView navigationView) - { - this.navigationView = navigationView; - navigationView.ItemInvoked += OnItemInvoked; - } - } - } -}