308 Commits

Author SHA1 Message Date
chinboy 28639b343a feat(BrowserGallery): integrate FloatButtonShowCase and enhance lazy loading for improved navigation 2026-06-07 22:43:54 +08:00
chinboy 3d9a5f5c5e feat(Icon): remove motion-related properties and clean up icon themes 2026-06-07 22:15:08 +08:00
chinboy cbb69e5457 feat(BrowserGallery): integrate ButtonShowCase and enhance navigation with lazy loading 2026-06-07 21:03:14 +08:00
chinboy bbd7a44341 feat(BrowserGallery): enhance gallery with IconShowCase integration and input themes 2026-06-07 18:23:53 +08:00
chinboy 99cc82ef3a feat(Browser): add palette showcase with tab fallbacks 2026-06-07 18:04:02 +08:00
chinboy 013e18ffc2 feat(Browser): add gallery browser host with control fallbacks 2026-06-07 17:45:00 +08:00
chinboy 1c62e45646 feat(TreeView,TreeSelect)!: rename tree filter strategy API 2026-06-05 18:23:35 +08:00
chinboy a9ebf2ecfa docs(Gallery): document localized option data rules 2026-06-03 17:24:59 +08:00
chinboy 459275f9e0 gallery(i18n): localize showcase examples and fix resource binding 2026-06-03 13:21:23 +08:00
chinboy e6a5695049 gallery(i18n): localize showcase titles and descriptions 2026-06-02 22:09:26 +08:00
chinboy ff8faa951f docs: remove obsolete audit and performance notes 2026-06-02 18:08:37 +08:00
chinboy cf28844106 docs(Gallery): add showcase organization guidelines 2026-06-02 17:43:55 +08:00
chinboy 3d3f29075f docs(api): add global consistency audit 2026-06-02 11:03:18 +08:00
chinboy 6fbb65cf53 perf(controls): reduce allocation and startup overhead 2026-06-02 08:08:55 +08:00
chinboy 44d226f213 perf(controls): reduce allocation and flag-check overhead 2026-06-01 16:26:36 +08:00
chinboy 4627188951 docs(performance): update controls optimization reports 2026-05-31 17:51:42 +08:00
chinboy 59c99395bf docs(performance): update controls optimization summary 2026-05-31 09:34:36 +08:00
chinboy 3cb96920ae perf(DataGrid): reduce column detach overhead 2026-05-31 09:34:23 +08:00
chinboy 56d95e009b perf(selection): reduce tree and transfer overhead 2026-05-31 09:34:04 +08:00
chinboy 7527237ec6 perf(navigation): reduce hit-test and motion overhead 2026-05-31 09:33:49 +08:00
chinboy df79b65569 perf(inputs): reduce picker and input state overhead 2026-05-31 09:33:26 +08:00
chinboy bb59f6f7ae perf(controls): optimize collection synchronization paths 2026-05-31 09:32:58 +08:00
chinboy d0efaca4eb perf(VisualLayers): reduce layer lookup and render overhead 2026-05-31 09:32:39 +08:00
chinboy ae001efb6b perf(ColorPicker): reduce gradient and brush update overhead 2026-05-31 09:32:23 +08:00
chinboy 106a9961cb perf(Badge): reduce badge adorner and motion overhead 2026-05-31 09:32:13 +08:00
chinboy 915deff4eb perf(controls): reduce allocation and state sync overhead 2026-05-29 17:40:13 +08:00
chinboy 6f4bbdc064 perf(controls): reduce transfer, tree and layout overhead 2026-05-29 10:32:40 +08:00
chinboy 9b83aa5940 perf(PopupConfirm): optimize button event lifecycle and correctness 2026-05-28 23:08:04 +08:00
chinboy 4a60c55fc2 perf(controls): optimize flyout and layout lifecycles 2026-05-28 21:48:10 +08:00
chinboy 9379c9a0c5 perf(controls): optimize ColorPicker, titlebar and adorner lifecycles 2026-05-28 11:50:30 +08:00
chinboy 8974f9cf6f docs(DataGrid): close remaining performance audit items 2026-05-28 10:01:41 +08:00
chinboy 3eefb30d8b perf(DataGrid): reduce data-layer and column group overhead 2026-05-28 09:13:01 +08:00
chinboy c621706a52 perf(DataGrid): add verification for item-type probe enumerator disposal 2026-05-27 15:55:41 +08:00
chinboy 393b376189 perf(DataGrid): reduce filter and data-layer overhead 2026-05-27 15:32:01 +08:00
chinboy d55bc01c52 perf(DataGrid): reduce allocation and lifecycle overhead 2026-05-26 19:38:27 +08:00
chinboy a4e07782fa perf(DataGrid): reuse row group header transforms
Cache DataGridRowGroupHeader frozen child TranslateTransform instances across repeated arrange passes, update X in place, and clear child RenderTransform values when row group headers become fully frozen, re-templated, or detached.

Qualification: DataGridShowCase declares 65 DataGrid instances; grouped grids with row headers and horizontal scrolling exercise row group header frozen child arrange paths. Operation frequency: horizontal scrolling, row group header layout, row group header frozen-state changes, re-template, and detach.

Avalonia basis: Visual.RenderTransform is a styled property and Avalonia subscribes mutable Transform.Changed to invalidate the visual (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:92-100,150,644-710). TranslateTransform.X/Y changes raise Transform.Changed (.referenceprojects/Avalonia/src/Avalonia.Base/Media/TranslateTransform.cs:14-22,70-75; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Transform.cs:23-50).

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check; git diff --cached --check.
2026-05-26 10:37:47 +08:00
chinboy 2f41df5b7c perf(DataGrid): reduce row clip allocation
Reuse DataGridRow hidden clip geometry for non-recyclable hidden rows and cache DataGridRowGroupHeader child clip geometries across repeated arrange passes. Also resolve the built-in RowGroupHeader RootLayout/RowHeader template part names so row header visibility, owner wiring, and child clip lifecycle run for the shipped template.

Qualification: DataGridShowCase declares 65 DataGrid instances; row virtualization/removal paths apply to realized rows, and row group header child clipping applies to grouped grids with row headers/frozen offsets. Operation frequency: vertical scrolling, ItemsSource changes, row deletion, row clearing, horizontal scrolling, row group header layout, re-template, and detach.

Avalonia basis: Visual.Clip is a styled property registered with AffectsRender and InvalidateVisual queues dirty rendering (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.RectProperty marks geometry dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check; git diff --cached --check.
2026-05-26 10:12:26 +08:00
chinboy 2925af953f perf(DataGrid): reduce reordering indicator clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances and 210 column declarations. Column reordering is available on the column header presenters, and the optimized path applies to drag and drop-location indicators clipped by frozen column regions during standard and grouped header reordering.

Operation frequency: column reordering indicator arrange/clip updates can run during pointer move, auto-scroll, horizontal scrolling, resizing, and grid relayout while a column is being dragged. Previously each clipped indicator update allocated a new RectangleGeometry.

Avalonia source basis: Visual.Clip is a styled property registered with AffectsRender, and InvalidateVisual marks the visual dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.Rect participates in geometry invalidation (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Benefit: repeated clipped column reordering indicator updates now reuse cached RectangleGeometry instances after first use, reducing repeated clip geometry allocation from 1/clipped indicator update to 0 after first while preserving Clip clearing when clipping is no longer needed or an indicator is replaced.

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check.
2026-05-26 09:29:10 +08:00
chinboy e64267c11f perf(DataGrid): reduce group header clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances and 210 column declarations. Grouped header scenarios include DataGridColumnGroupItem leaves, and frozen-column examples use LeftFrozenColumnCount and RightFrozenColumnCount. The optimized path applies to grouped leaf DataGridHeaderViewItem instances that require clipping under frozen columns.

Operation frequency: group column header presenter arrange runs during initial layout, horizontal scrolling, resizing, column width changes, and grid relayout. Previously each clipped grouped leaf header arrange allocated a new RectangleGeometry.

Avalonia source basis: Visual.Clip is a styled property registered with AffectsRender, and InvalidateVisual marks the visual dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.Rect participates in geometry invalidation (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Benefit: repeated clipped group column header view item arrange now reuses one RectangleGeometry after first use, reducing repeated clip geometry allocation from 1/clipped grouped leaf header arrange to 0 after first while preserving Clip clearing when clipping is no longer needed.

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check.
2026-05-26 08:59:59 +08:00
chinboy a58b30355d perf(DataGrid): reduce column header clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances and 210 column declarations, including multiple frozen-column examples with LeftFrozenColumnCount and RightFrozenColumnCount. The optimized path applies to realized DataGridColumnHeader instances that require clipping under frozen columns or header viewport constraints.

Operation frequency: column header presenter arrange runs during initial layout, horizontal scrolling, resizing, column width changes, and grid relayout. Previously each clipped header arrange allocated a new RectangleGeometry.

Avalonia source basis: Visual.Clip is a styled property registered with AffectsRender, and InvalidateVisual marks the visual dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.Rect participates in geometry invalidation (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Benefit: repeated clipped column header arrange now reuses one RectangleGeometry after first use, reducing repeated clip geometry allocation from 1/clipped header arrange to 0 after first while preserving Clip clearing when clipping is no longer needed.

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check.
2026-05-26 08:47:23 +08:00
chinboy d827dd12f7 perf(DataGrid): reduce cell clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances, including multiple frozen-column examples with LeftFrozenColumnCount and RightFrozenColumnCount. The optimized path applies to realized DataGridCell instances that require clipping under frozen columns or horizontal virtualization.

Operation frequency: cells presenter arrange runs during initial layout, horizontal scrolling, resizing, column width changes, grid relayout, and row virtualization reuse. Previously each clipped cell arrange allocated a new RectangleGeometry.

Avalonia source basis: Visual.Clip is a styled property registered with AffectsRender, and InvalidateVisual marks the visual dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.Rect participates in geometry invalidation (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Benefit: repeated clipped cell arrange now reuses one RectangleGeometry after first use, reducing repeated clip geometry allocation from 1/clipped cell arrange to 0 after first while preserving Clip clearing when clipping is no longer needed.

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check.
2026-05-26 08:15:39 +08:00
chinboy 2c47bce767 perf(DataGrid): reduce details presenter clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances. Row details scenarios create DataGridDetailsPresenter per templated row, but this allocation path only applies to visible non-frozen row details during arrange.

Operation frequency: visible row details arrange during initial layout, horizontal scrolling, resizing, grid relayout, and row details visibility/frozen-state changes.

Avalonia source basis: Visual.Clip is a styled property registered with AffectsRender, and InvalidateVisual marks the visual dirty (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421,446-500). RectangleGeometry.Rect participates in geometry invalidation (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Benefit: repeated non-frozen details arrange now reuses one RectangleGeometry after first use, reducing repeated clip geometry allocation from 1/details arrange to 0 after first while preserving frozen Clip clearing.

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100; git diff --check.
2026-05-26 07:42:44 +08:00
chinboy 5e366bb34a perf(DataGrid): reduce row gridline clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances; each realized DataGrid creates multiple DataGridRow instances, and every templated row owns one PART_BottomGridLine.

Operation frequency: DataGridRow.ArrangeOverride runs during page navigation layout, resizing, horizontal scrolling, row recycling, and grid relayout; the previous code allocated one RectangleGeometry for the bottom gridline on each realized row arrange.

Avalonia basis: Visual.Clip is a StyledProperty registered with AffectsRender and InvalidateVisual queues the visual for repaint (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421). RectangleGeometry.RectProperty is registered with AffectsGeometry, so the reused geometry updates its platform geometry while this change explicitly invalidates the bottom gridline when Rect changes (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100.
2026-05-26 07:23:33 +08:00
chinboy cd9613d0bc perf(DataGrid): reduce rows presenter clip allocation
Gallery qualification: DataGridShowCase declares 65 DataGrid instances, and each realized DataGrid template owns one DataGridRowsPresenter.

Operation frequency: DataGridRowsPresenter.ArrangeOverride runs during page navigation layout, resizing, and scroll-triggered layout passes; the previous code allocated one RectangleGeometry per arrange.

Avalonia basis: Visual.Clip is a StyledProperty registered with AffectsRender and InvalidateVisual queues the visual for repaint (.referenceprojects/Avalonia/src/Avalonia.Base/Visual.cs:52-53,141-149,418-421). RectangleGeometry.RectProperty is registered with AffectsGeometry, so the reused geometry updates its platform geometry while this change explicitly invalidates the presenter when Rect changes (.referenceprojects/Avalonia/src/Avalonia.Base/Media/RectangleGeometry.cs:25-33; .referenceprojects/Avalonia/src/Avalonia.Base/Media/Geometry.cs:146-172).

Verification: dotnet build -c Release -f net10.0 tools/performances/AtomUI.Performance/AtomUI.Performance.csproj; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --verify-datagrid-states; dotnet run -c Release -f net10.0 --no-build --project tools/performances/AtomUI.Performance/AtomUI.Performance.csproj -- --suite datagrid --count 100.
2026-05-26 07:10:17 +08:00
chinboy db61a51160 perf(DataGrid): reduce rows presenter scroll handler overhead
Gallery qualification: DataGridShowCase declares 65 DataGrid instances, and each template creates one DataGridRowsPresenter. This removes one constructor-time local ScrollGesture routed subscription per rows presenter. Setup happens whenever a DataGrid template is realized; ScrollGesture runs when users scroll DataGrid rows with touchpad or gesture input.

Behavior: DataGridRowsPresenter now handles ScrollGesture through a class handler and still calls the existing OwningGrid.UpdateScroll(-e.Delta) path. State verification confirms no local ScrollGesture handler remains, the gesture is still marked handled when scrolling occurs, and VerticalOffset still changes.

Documentation: updates the DataGrid performance notes and roadmap, and adds the performance-skill rule that every optimization completion must proactively report benefit in a table with baseline, optimized, formula, improvement, and conclusion.

Avalonia basis: ScrollGestureEvent is a bubble routed event. Event adders call AddHandler and store local routed subscriptions in Interactive._eventHandlers, while AddClassHandler subscribes once through RoutedEvent.Raised and filters by route/type.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.Gestures.cs:65-69; .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.Gestures.cs:197-200; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:30-64; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:176-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:78-99.
2026-05-26 06:53:44 +08:00
chinboy bb5811bb63 perf(DataGrid): reduce core input handler overhead
Gallery qualification: DataGridShowCase declares 65 DataGrid instances, so constructor-time subscriptions are multiplied during page navigation and Gallery setup. This change removes four core input routed subscriptions per grid instance. Setup happens whenever a DataGrid is constructed; KeyDown, KeyUp, GotFocus, and LostFocus run during keyboard navigation and focus movement inside the grid.

Behavior: DataGrid now uses OnKeyDown, OnKeyUp, OnGotFocus, and OnLostFocus overrides to call the existing handler bodies with the same !Handled guard. State verification confirms the grid no longer has local core input handlers, GotFocus still updates ContainsFocus, and Down key navigation still moves the current slot.

Avalonia basis: InputElement registers class handlers that dispatch GotFocus, LostFocus, KeyDown, and KeyUp to the virtual OnGotFocus, OnLostFocus, OnKeyDown, and OnKeyUp methods. Event adders call AddHandler and store per-instance subscriptions in Interactive._eventHandlers; RoutedEvent.AddClassHandler uses RoutedEvent.Raised and route filtering.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:235-240; .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:596-657; .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:106-118; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:30-64; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:176-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:78-99.
2026-05-25 20:38:58 +08:00
chinboy 17baabdbe7 perf(DataGrid): reduce row group header press overhead
Gallery qualification: DataGridRowGroupHeader is created per realized row group header in grouped DataGrid views. The DataGrid.RowGroups smoke scenario realizes grouped headers during page setup, and grouped DataGrid pages create these headers during navigation or grouped data display. Setup happens when a new group header instance is created; PointerPressed runs whenever users click a group header to update current slot or toggle grouping behavior.

Correctness: DataGridRowHeader now retries owner-dependent template state from the Owner setter, preventing a null OwningGrid path when a group header template applies the row header before assigning Owner.

Avalonia basis: PointerPressed is a tunnel+bubble routed event. Event adders call AddHandler and store local routed subscriptions in Interactive._eventHandlers, while AddClassHandler subscribes once through RoutedEvent.Raised for the control type. EventRoute still honors handledEventsToo, preserving the original handled-event behavior.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:158-169; .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:380-383; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:176-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:78-99; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/EventRoute.cs:158-170.
2026-05-25 19:20:16 +08:00
chinboy e0c1dd54cc perf(DataGrid): reduce row header press handler overhead
Gallery qualification: DataGridRowHeader is the row template header slot created per realized DataGridRow. DataGrid.RowHeaders realizes 8 visible row headers in the performance smoke path, and DataGridShowCase row header, row details, and special-column examples create these headers during page navigation. Setup happens once per realized row during navigation; PointerPressed runs each time a user clicks a row header.

Avalonia basis: PointerPressed is a tunnel+bubble routed event. Event adders call AddHandler and store local routed subscriptions in Interactive._eventHandlers, while AddClassHandler subscribes once through RoutedEvent.Raised for the control type. EventRoute still honors handledEventsToo, so the row header selection path keeps the original handled-event behavior.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:158-169; .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:380-383; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:176-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:78-99; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/EventRoute.cs:158-170.
2026-05-25 18:58:13 +08:00
chinboy 4b8fd36530 perf(DataGrid): reduce group header forwarding overhead
Gallery qualification: DataGridShowCase has one Grouping table head example with 4 DataGridColumnGroupItem instances. The group headers are realized during DataGrid page navigation, and their header pointer forwarding runs when users press or release grouped headers. Although the instance count is small, this removes the remaining per-header routed subscriptions in the column header cleanup path with no visual or API change.

Avalonia basis: PointerPressed/PointerReleased event adders call AddHandler and store local routed subscriptions in Interactive._eventHandlers, while AddClassHandler subscribes once through RoutedEvent.Raised for the control type.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:380-392; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:30-42; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:179-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:78-99.
2026-05-25 18:31:32 +08:00
chinboy 02bda1f152 perf(DataGrid): reduce row expander and header handler overhead
Gallery qualification: DataGridShowCase declares 65 DataGrid controls and 210 columns; column headers and row expanders are realized during page navigation, header press/release/move runs during resize/reorder/sort, and row details binding runs on row load plus expand/collapse.

Avalonia basis: Pointer event adders call AddHandler and store local subscriptions in Interactive._eventHandlers, while AddClassHandler subscribes once through RoutedEvent.Raised. GetObservable/Bind(IObservable<T>) uses direct observable binding, while BindUtils.RelayBind creates Binding + Source + Path.

Sources: .referenceprojects/Avalonia/src/Avalonia.Base/Input/InputElement.cs:353-389; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/Interactive.cs:176-190; .referenceprojects/Avalonia/src/Avalonia.Base/Interactivity/RoutedEvent.cs:84-99; .referenceprojects/Avalonia/src/Avalonia.Base/AvaloniaObjectExtensions.cs:59-77; src/AtomUI.Core/Data/BindUtils.cs:8-36.
2026-05-25 18:19:10 +08:00