From 1c8cc1f733b24f25bd77a1dd00a509d064816038 Mon Sep 17 00:00:00 2001 From: CHINBOY Date: Tue, 24 Jun 2025 19:05:17 +0800 Subject: [PATCH] Refactor TreeViewItem --- .../Column/Filters/DataGridFilterIndicator.cs | 58 ++++++++++++------- .../Filters/DataGridTreeFilterFlyout.cs | 21 +++++++ src/AtomUI.Controls/TreeView/TreeViewItem.cs | 19 +++++- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridFilterIndicator.cs b/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridFilterIndicator.cs index f45cef96e..2fcaadcf2 100644 --- a/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridFilterIndicator.cs +++ b/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridFilterIndicator.cs @@ -1,6 +1,8 @@ using System.Diagnostics; +using AtomUI.Controls.DataGridLang; using AtomUI.Data; using AtomUI.IconPkg.AntDesign; +using AtomUI.Theme.Data; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; @@ -12,38 +14,39 @@ namespace AtomUI.Controls; internal class DataGridFilterIndicator : IconButton { #region 公共属性定义 - - public static readonly StyledProperty IsFilterActivatedProperty - = AvaloniaProperty.Register(nameof(IsFilterActivated)); - + + public static readonly StyledProperty IsFilterActivatedProperty = + AvaloniaProperty.Register(nameof(IsFilterActivated)); + public static readonly DirectProperty FilterModeProperty = AvaloniaProperty.RegisterDirect( nameof(FilterMode), o => o.FilterMode, (o, v) => o.FilterMode = v); - + public static readonly StyledProperty ToggleTypeProperty = MenuItem.ToggleTypeProperty.AddOwner(); - + public bool IsFilterActivated { get => GetValue(IsFilterActivatedProperty); set => SetValue(IsFilterActivatedProperty, value); } - + private DataGridFilterMode _filterMode; + public DataGridFilterMode FilterMode { get => _filterMode; set => SetAndRaise(FilterModeProperty, ref _filterMode, value); } - + public MenuItemToggleType ToggleType { get => GetValue(ToggleTypeProperty); set => SetValue(ToggleTypeProperty, value); } - + #endregion private DataGridColumn? _owningColumn; @@ -63,6 +66,7 @@ internal class DataGridFilterIndicator : IconButton } } } + private readonly FlyoutStateHelper _flyoutStateHelper; public DataGridFilterIndicator() @@ -86,8 +90,10 @@ internal class DataGridFilterIndicator : IconButton } } } + return true; } + return false; } }; @@ -113,7 +119,7 @@ internal class DataGridFilterIndicator : IconButton CreateFlyout(); } } - + private void CreateFlyout() { Debug.Assert(OwningColumn is not null); @@ -127,12 +133,14 @@ internal class DataGridFilterIndicator : IconButton Placement = PlacementMode.BottomEdgeAlignedRight, IsDetectMouseClickEnabled = false }; - BindUtils.RelayBind(owningGrid, MotionAwareControlProperty.IsMotionEnabledProperty, menuFlyout, MotionAwareControlProperty.IsMotionEnabledProperty); + BindUtils.RelayBind(owningGrid, MotionAwareControlProperty.IsMotionEnabledProperty, menuFlyout, + MotionAwareControlProperty.IsMotionEnabledProperty); var menuItems = BuildMenuItems(OwningColumn.Filters.ToList()); foreach (var menuItem in menuItems) { menuFlyout.Items.Add(menuItem); } + Flyout = menuFlyout; _flyoutStateHelper.Flyout = menuFlyout; } @@ -144,12 +152,18 @@ internal class DataGridFilterIndicator : IconButton Placement = PlacementMode.BottomEdgeAlignedRight, IsDetectMouseClickEnabled = false }; - BindUtils.RelayBind(owningGrid, MotionAwareControlProperty.IsMotionEnabledProperty, treeFlyout, MotionAwareControlProperty.IsMotionEnabledProperty); - var treeItems = BuildTreeItems(OwningColumn.Filters.ToList()); + BindUtils.RelayBind(owningGrid, MotionAwareControlProperty.IsMotionEnabledProperty, treeFlyout, + MotionAwareControlProperty.IsMotionEnabledProperty); + var selectAllTreeItem = new DataGridFilterTreeItem(); + LanguageResourceBinder.CreateBinding(selectAllTreeItem, DataGridFilterTreeItem.HeaderProperty, + DataGridLangResourceKey.SelectAllFilterItems); + var treeItems = BuildTreeItems(OwningColumn.Filters.ToList()); foreach (var menuItem in treeItems) { - treeFlyout.Items.Add(menuItem); + selectAllTreeItem.Items.Add(menuItem); } + + treeFlyout.Items.Add(selectAllTreeItem); Flyout = treeFlyout; _flyoutStateHelper.Flyout = treeFlyout; } @@ -178,6 +192,7 @@ internal class DataGridFilterIndicator : IconButton } } } + return menuItems; } @@ -188,8 +203,8 @@ internal class DataGridFilterIndicator : IconButton { var treeItem = new DataGridFilterTreeItem() { - Header = item.Text, - FilterValue = item.Value + Header = item.Text, + FilterValue = item.Value }; treeItems.Add(treeItem); if (item.Children.Count > 0) @@ -201,9 +216,10 @@ internal class DataGridFilterIndicator : IconButton } } } + return treeItems; } - + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); @@ -215,14 +231,14 @@ internal class DataGridFilterIndicator : IconButton base.OnAttachedToVisualTree(e); _flyoutStateHelper.NotifyAttachedToVisualTree(); } - + protected override void OnClick() { if (IsEffectivelyEnabled) { var e = new RoutedEventArgs(ClickEvent); RaiseEvent(e); - var ( command, parameter) = (Command, CommandParameter); + var (command, parameter) = (Command, CommandParameter); if (!e.Handled && command is not null && command.CanExecute(parameter)) { command.Execute(parameter); @@ -230,5 +246,7 @@ internal class DataGridFilterIndicator : IconButton } } } - + + + } \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridTreeFilterFlyout.cs b/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridTreeFilterFlyout.cs index a3aecfde9..be4f86cf0 100644 --- a/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridTreeFilterFlyout.cs +++ b/src/AtomUI.Controls.DataGrid/Column/Filters/DataGridTreeFilterFlyout.cs @@ -1,5 +1,6 @@ using AtomUI.Data; using Avalonia.Controls; +using Avalonia.Input; using Avalonia.Metadata; namespace AtomUI.Controls; @@ -30,4 +31,24 @@ public class DataGridTreeFilterFlyout : Flyout internal class DataGridFilterTreeItem : TreeViewItem { public string? FilterValue { get; set; } + + protected override void NotifyHeaderClick() + { + if (IsChecked is null) + { + IsChecked = true; + } + else + { + IsChecked = !IsChecked; + } + } + + protected override void OnHeaderDoubleTapped(TappedEventArgs e) + { + if (ItemCount > 0) + { + e.Handled = true; + } + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/TreeView/TreeViewItem.cs b/src/AtomUI.Controls/TreeView/TreeViewItem.cs index a98afdde9..1489f69eb 100644 --- a/src/AtomUI.Controls/TreeView/TreeViewItem.cs +++ b/src/AtomUI.Controls/TreeView/TreeViewItem.cs @@ -63,8 +63,8 @@ public class TreeViewItem : AvaloniaTreeItem, public static readonly StyledProperty IsShowLeafIconProperty = AvaloniaProperty.Register(nameof(IsShowLeafIcon)); - public static readonly StyledProperty IsLoadingProperty - = AvaloniaProperty.Register(nameof(IsLoading), false); + public static readonly StyledProperty IsLoadingProperty = + AvaloniaProperty.Register(nameof(IsLoading), false); public bool IsCheckable { @@ -871,4 +871,19 @@ public class TreeViewItem : AvaloniaTreeItem, { return new DragPreviewAdorner(_frame!); } + + protected override void OnPointerReleased(PointerReleasedEventArgs e) + { + base.OnPointerReleased(e); + var bounds = new Rect(new Point(0, 0), _headerPresenter?.DesiredSize ?? default); + var point = e.GetPosition(_headerPresenter); + if (bounds.Contains(point)) + { + NotifyHeaderClick(); + } + } + + protected virtual void NotifyHeaderClick() + { + } } \ No newline at end of file