From c6f440bd56b929a3f293ec790084d8a5b4896d4f Mon Sep 17 00:00:00 2001 From: rabbitism Date: Mon, 12 Feb 2024 21:42:05 +0800 Subject: [PATCH] wip: simplify container preparation. --- demo/Ursa.Demo/Pages/NavMenuDemo.axaml | 10 ++- src/Ursa.Themes.Semi/Controls/NavMenu.axaml | 13 ++-- src/Ursa/Controls/NavMenu/NavMenu.cs | 50 ++++++-------- src/Ursa/Controls/NavMenu/NavMenuItem.cs | 74 ++++++++++++++------- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/demo/Ursa.Demo/Pages/NavMenuDemo.axaml b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml index 05edc59..0b192bb 100644 --- a/demo/Ursa.Demo/Pages/NavMenuDemo.axaml +++ b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml @@ -48,9 +48,15 @@ + IconBinding="{Binding}"> + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/NavMenu.axaml b/src/Ursa.Themes.Semi/Controls/NavMenu.axaml index 2f24300..9a98a0d 100644 --- a/src/Ursa.Themes.Semi/Controls/NavMenu.axaml +++ b/src/Ursa.Themes.Semi/Controls/NavMenu.axaml @@ -17,7 +17,7 @@ - + @@ -25,15 +25,16 @@ + Content="{TemplateBinding Icon}" + ContentTemplate="{TemplateBinding IconTemplate}" /> + Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" /> - + diff --git a/src/Ursa/Controls/NavMenu/NavMenu.cs b/src/Ursa/Controls/NavMenu/NavMenu.cs index 38baf33..851dbb2 100644 --- a/src/Ursa/Controls/NavMenu/NavMenu.cs +++ b/src/Ursa/Controls/NavMenu/NavMenu.cs @@ -2,6 +2,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.LogicalTree; using Avalonia.Metadata; @@ -63,6 +64,24 @@ public class NavMenu: ItemsControl set => SetValue(CommandBindingProperty, value); } + public static readonly StyledProperty HeaderTemplateProperty = AvaloniaProperty.Register( + nameof(HeaderTemplate)); + + public IDataTemplate? HeaderTemplate + { + get => GetValue(HeaderTemplateProperty); + set => SetValue(HeaderTemplateProperty, value); + } + + public static readonly StyledProperty IconTemplateProperty = AvaloniaProperty.Register( + nameof(IconTemplate)); + + public IDataTemplate? IconTemplate + { + get => GetValue(IconTemplateProperty); + set => SetValue(IconTemplateProperty, value); + } + static NavMenu() { SelectedItemProperty.Changed.AddClassHandler((o, e) => o.OnSelectedItemChange(e)); @@ -83,30 +102,6 @@ public class NavMenu: ItemsControl return new NavMenuItem(); } - protected override void PrepareContainerForItemOverride(Control container, object? item, int index) - { - base.PrepareContainerForItemOverride(container, item, index); - if (container is NavMenuItem navMenuItem) - { - if (IconBinding is not null) - { - navMenuItem[!NavMenuItem.IconProperty] = IconBinding; - } - if (HeaderBinding is not null) - { - navMenuItem[!HeaderedItemsControl.HeaderProperty] = HeaderBinding; - } - if (SubMenuBinding is not null) - { - navMenuItem[!ItemsSourceProperty] = SubMenuBinding; - } - if (CommandBinding is not null) - { - navMenuItem[!NavMenuItem.CommandProperty] = CommandBinding; - } - } - } - internal void SelectItem(NavMenuItem item, NavMenuItem parent) { // if (item.IsSelected) return; @@ -116,12 +111,9 @@ public class NavMenu: ItemsControl { continue; } - else + if (child is NavMenuItem navMenuItem) { - if (child is NavMenuItem navMenuItem) - { - navMenuItem.ClearSelection(); - } + navMenuItem.ClearSelection(); } } if (item.DataContext is not null && item.DataContext != this.DataContext) diff --git a/src/Ursa/Controls/NavMenu/NavMenuItem.cs b/src/Ursa/Controls/NavMenu/NavMenuItem.cs index da05dcd..8737ab8 100644 --- a/src/Ursa/Controls/NavMenu/NavMenuItem.cs +++ b/src/Ursa/Controls/NavMenu/NavMenuItem.cs @@ -83,6 +83,28 @@ public class NavMenuItem: HeaderedSelectingItemsControl get => _isHighlighted; private set => SetAndRaise(IsHighlightedProperty, ref _isHighlighted, value); } + + private bool _isCollapsed; + + public static readonly DirectProperty IsCollapsedProperty = AvaloniaProperty.RegisterDirect( + nameof(IsCollapsed), o => o.IsCollapsed, (o, v) => o.IsCollapsed = v); + + public bool IsCollapsed + { + get => _isCollapsed; + set => SetAndRaise(IsCollapsedProperty, ref _isCollapsed, value); + } + + private bool _isClosed; + + public static readonly DirectProperty IsClosedProperty = AvaloniaProperty.RegisterDirect( + nameof(IsClosed), o => o.IsClosed, (o, v) => o.IsClosed = v); + + public bool IsClosed + { + get => _isClosed; + set => SetAndRaise(IsClosedProperty, ref _isClosed, value); + } internal int Level { get; set; } @@ -109,35 +131,33 @@ public class NavMenuItem: HeaderedSelectingItemsControl { return new NavMenuItem(); } - - protected override void PrepareContainerForItemOverride(Control container, object? item, int index) - { - base.PrepareContainerForItemOverride(container, item, index); - if (container is NavMenuItem navMenuItem) - { - if (_rootMenu?.HeaderBinding is not null) - { - container[!HeaderProperty] = _rootMenu.HeaderBinding; - } - if (_rootMenu?.IconBinding is not null) - { - container[!IconProperty] = _rootMenu.IconBinding; - } - if (_rootMenu?.SubMenuBinding is not null) - { - container[!ItemsSourceProperty] = _rootMenu.SubMenuBinding; - } - if (_rootMenu?.CommandBinding is not null) - { - container[!CommandProperty] = _rootMenu.CommandBinding; - } - } - } - + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); _rootMenu = GetRootMenu(); + if (_rootMenu is not null) + { + if (_rootMenu.IconBinding is not null) + { + this[!IconProperty] = _rootMenu.IconBinding; + } + if (_rootMenu.HeaderBinding is not null) + { + this[!HeaderProperty] = _rootMenu.HeaderBinding; + } + if (_rootMenu.SubMenuBinding is not null) + { + this[!ItemsSourceProperty] = _rootMenu.SubMenuBinding; + } + if (_rootMenu.CommandBinding is not null) + { + this[!CommandProperty] = _rootMenu.CommandBinding; + } + this[!IconTemplateProperty] = _rootMenu[!NavMenu.IconTemplateProperty]; + this[!HeaderTemplateProperty] = _rootMenu[!NavMenu.HeaderTemplateProperty]; + } + } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) @@ -154,6 +174,10 @@ public class NavMenuItem: HeaderedSelectingItemsControl if (this.ItemCount == 0) { SelectItem(this); + } + else + { + } Command?.Execute(CommandParameter); e.Handled = true;