From 25d8b86992fd326efbb15cabd9e89a2116a7a96d Mon Sep 17 00:00:00 2001 From: robloo Date: Sat, 3 Dec 2022 10:48:00 -0500 Subject: [PATCH 001/157] Add new IsCheckedChanged event to ToggleButton Old events are now obsoleted --- .../Primitives/ToggleButton.cs | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/ToggleButton.cs b/src/Avalonia.Controls/Primitives/ToggleButton.cs index 148797c53a..93ec17f0ca 100644 --- a/src/Avalonia.Controls/Primitives/ToggleButton.cs +++ b/src/Avalonia.Controls/Primitives/ToggleButton.cs @@ -32,20 +32,37 @@ namespace Avalonia.Controls.Primitives /// /// Defines the event. /// + [Obsolete("Use IsCheckedChangedEvent instead.")] public static readonly RoutedEvent CheckedEvent = - RoutedEvent.Register(nameof(Checked), RoutingStrategies.Bubble); + RoutedEvent.Register( + nameof(Checked), + RoutingStrategies.Bubble); /// /// Defines the event. /// + [Obsolete("Use IsCheckedChangedEvent instead.")] public static readonly RoutedEvent UncheckedEvent = - RoutedEvent.Register(nameof(Unchecked), RoutingStrategies.Bubble); + RoutedEvent.Register( + nameof(Unchecked), + RoutingStrategies.Bubble); /// /// Defines the event. /// + [Obsolete("Use IsCheckedChangedEvent instead.")] public static readonly RoutedEvent IndeterminateEvent = - RoutedEvent.Register(nameof(Indeterminate), RoutingStrategies.Bubble); + RoutedEvent.Register( + nameof(Indeterminate), + RoutingStrategies.Bubble); + + /// + /// Defines the event. + /// + public static readonly RoutedEvent IsCheckedChangedEvent = + RoutedEvent.Register( + nameof(IsCheckedChanged), + RoutingStrategies.Bubble); private bool? _isChecked = false; @@ -62,6 +79,7 @@ namespace Avalonia.Controls.Primitives /// /// Raised when a is checked. /// + [Obsolete("Use IsCheckedChanged instead.")] public event EventHandler? Checked { add => AddHandler(CheckedEvent, value); @@ -71,6 +89,7 @@ namespace Avalonia.Controls.Primitives /// /// Raised when a is unchecked. /// + [Obsolete("Use IsCheckedChanged instead.")] public event EventHandler? Unchecked { add => AddHandler(UncheckedEvent, value); @@ -80,12 +99,22 @@ namespace Avalonia.Controls.Primitives /// /// Raised when a is neither checked nor unchecked. /// + [Obsolete("Use IsCheckedChanged instead.")] public event EventHandler? Indeterminate { add => AddHandler(IndeterminateEvent, value); remove => RemoveHandler(IndeterminateEvent, value); } + /// + /// Raised when the property value changes. + /// + public event EventHandler? IsCheckedChanged + { + add => AddHandler(IsCheckedChangedEvent, value); + remove => RemoveHandler(IsCheckedChangedEvent, value); + } + /// /// Gets or sets whether the is checked. /// @@ -182,13 +211,13 @@ namespace Avalonia.Controls.Primitives switch (newValue) { case true: - OnChecked(new RoutedEventArgs(CheckedEvent)); + OnChecked(new RoutedEventArgs(IsCheckedChangedEvent)); break; case false: - OnUnchecked(new RoutedEventArgs(UncheckedEvent)); + OnUnchecked(new RoutedEventArgs(IsCheckedChangedEvent)); break; default: - OnIndeterminate(new RoutedEventArgs(IndeterminateEvent)); + OnIndeterminate(new RoutedEventArgs(IsCheckedChangedEvent)); break; } } From 0a36aec64a1f312578b02e5d9dd63ac7e3c39b3a Mon Sep 17 00:00:00 2001 From: robloo Date: Sat, 3 Dec 2022 10:48:24 -0500 Subject: [PATCH 002/157] Fix IsCheckedChanged in ToggleSplitButton to be nullable --- src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs index 83bc9851c1..fd7ea28ba1 100644 --- a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs +++ b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs @@ -18,7 +18,7 @@ namespace Avalonia.Controls /// /// Raised when the property value changes. /// - public event EventHandler IsCheckedChanged + public event EventHandler? IsCheckedChanged { add => AddHandler(IsCheckedChangedEvent, value); remove => RemoveHandler(IsCheckedChangedEvent, value); From 59ee997516c1d96f1a7fe4c774bb36e619f7d963 Mon Sep 17 00:00:00 2001 From: robloo Date: Sat, 3 Dec 2022 10:50:56 -0500 Subject: [PATCH 003/157] Remove code section formatting blocks In later commits it was agreed not to include these in the future. --- .../SplitButton/SplitButton.cs | 20 ------------------- .../SplitButton/ToggleSplitButton.cs | 16 --------------- 2 files changed, 36 deletions(-) diff --git a/src/Avalonia.Controls/SplitButton/SplitButton.cs b/src/Avalonia.Controls/SplitButton/SplitButton.cs index f39064435d..b2139f01e9 100644 --- a/src/Avalonia.Controls/SplitButton/SplitButton.cs +++ b/src/Avalonia.Controls/SplitButton/SplitButton.cs @@ -68,10 +68,6 @@ namespace Avalonia.Controls private IDisposable? _flyoutPropertyChangedDisposable; - //////////////////////////////////////////////////////////////////////// - // Constructor / Destructors - //////////////////////////////////////////////////////////////////////// - /// /// Initializes a new instance of the class. /// @@ -79,10 +75,6 @@ namespace Avalonia.Controls { } - //////////////////////////////////////////////////////////////////////// - // Properties - //////////////////////////////////////////////////////////////////////// - /// /// Gets or sets the invoked when the primary part is pressed. /// @@ -123,10 +115,6 @@ namespace Avalonia.Controls /// protected override bool IsEnabledCore => base.IsEnabledCore && _commandCanExecute; - //////////////////////////////////////////////////////////////////////// - // Methods - //////////////////////////////////////////////////////////////////////// - /// void ICommandSource.CanExecuteChanged(object sender, EventArgs e) => this.CanExecuteChanged(sender, e); @@ -221,10 +209,6 @@ namespace Avalonia.Controls } } - //////////////////////////////////////////////////////////////////////// - // OnEvent Overridable Methods - //////////////////////////////////////////////////////////////////////// - /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { @@ -428,10 +412,6 @@ namespace Avalonia.Controls // Available for derived types } - //////////////////////////////////////////////////////////////////////// - // Event Handling - //////////////////////////////////////////////////////////////////////// - /// /// Event handler for when the internal primary button part is pressed. /// diff --git a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs index fd7ea28ba1..70d2983b9b 100644 --- a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs +++ b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs @@ -39,10 +39,6 @@ namespace Avalonia.Controls AvaloniaProperty.Register( nameof(IsChecked)); - //////////////////////////////////////////////////////////////////////// - // Constructor / Destructors - //////////////////////////////////////////////////////////////////////// - /// /// Initializes a new instance of the class. /// @@ -50,10 +46,6 @@ namespace Avalonia.Controls { } - //////////////////////////////////////////////////////////////////////// - // Properties - //////////////////////////////////////////////////////////////////////// - /// /// Gets or sets a value indicating whether the is checked. /// @@ -73,10 +65,6 @@ namespace Avalonia.Controls /// Type IStyleable.StyleKey => typeof(SplitButton); - //////////////////////////////////////////////////////////////////////// - // Methods - //////////////////////////////////////////////////////////////////////// - /// /// Toggles the property between true and false. /// @@ -85,10 +73,6 @@ namespace Avalonia.Controls IsChecked = !IsChecked; } - //////////////////////////////////////////////////////////////////////// - // OnEvent Overridable Methods - //////////////////////////////////////////////////////////////////////// - /// protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { From f4827bdfdbe22acb37132029975ed0fd711e8a65 Mon Sep 17 00:00:00 2001 From: robloo Date: Sat, 3 Dec 2022 10:52:29 -0500 Subject: [PATCH 004/157] Fix Click in SplitButton to be nullable --- src/Avalonia.Controls/SplitButton/SplitButton.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/SplitButton/SplitButton.cs b/src/Avalonia.Controls/SplitButton/SplitButton.cs index b2139f01e9..353674b26e 100644 --- a/src/Avalonia.Controls/SplitButton/SplitButton.cs +++ b/src/Avalonia.Controls/SplitButton/SplitButton.cs @@ -24,7 +24,7 @@ namespace Avalonia.Controls /// /// Raised when the user presses the primary part of the . /// - public event EventHandler Click + public event EventHandler? Click { add => AddHandler(ClickEvent, value); remove => RemoveHandler(ClickEvent, value); @@ -34,7 +34,9 @@ namespace Avalonia.Controls /// Defines the event. /// public static readonly RoutedEvent ClickEvent = - RoutedEvent.Register(nameof(Click), RoutingStrategies.Bubble); + RoutedEvent.Register( + nameof(Click), + RoutingStrategies.Bubble); /// /// Defines the property. From 0bb1b2ec03c7caf68d9a9fdcfa77d11ed51ce518 Mon Sep 17 00:00:00 2001 From: robloo Date: Sat, 3 Dec 2022 11:37:45 -0500 Subject: [PATCH 005/157] Fix ToggleButton tests --- .../Primitives/ToggleButton.cs | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/ToggleButton.cs b/src/Avalonia.Controls/Primitives/ToggleButton.cs index 93ec17f0ca..dfb436a55e 100644 --- a/src/Avalonia.Controls/Primitives/ToggleButton.cs +++ b/src/Avalonia.Controls/Primitives/ToggleButton.cs @@ -68,7 +68,6 @@ namespace Avalonia.Controls.Primitives static ToggleButton() { - IsCheckedProperty.Changed.AddClassHandler((x, e) => x.OnIsCheckedChanged(e)); } public ToggleButton() @@ -176,6 +175,7 @@ namespace Avalonia.Controls.Primitives /// Called when becomes true. /// /// Event arguments for the routed event that is raised by the default implementation of this method. + [Obsolete("Use OnIsCheckedChanged instead.")] protected virtual void OnChecked(RoutedEventArgs e) { RaiseEvent(e); @@ -185,6 +185,7 @@ namespace Avalonia.Controls.Primitives /// Called when becomes false. /// /// Event arguments for the routed event that is raised by the default implementation of this method. + [Obsolete("Use OnIsCheckedChanged instead.")] protected virtual void OnUnchecked(RoutedEventArgs e) { RaiseEvent(e); @@ -194,31 +195,51 @@ namespace Avalonia.Controls.Primitives /// Called when becomes null. /// /// Event arguments for the routed event that is raised by the default implementation of this method. + [Obsolete("Use OnIsCheckedChanged instead.")] protected virtual void OnIndeterminate(RoutedEventArgs e) { RaiseEvent(e); } + /// + /// Called when changes. + /// + /// Event arguments for the routed event that is raised by the default implementation of this method. + protected virtual void OnIsCheckedChanged(RoutedEventArgs e) + { + RaiseEvent(e); + } + protected override AutomationPeer OnCreateAutomationPeer() { return new ToggleButtonAutomationPeer(this); } - private void OnIsCheckedChanged(AvaloniaPropertyChangedEventArgs e) + /// + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { - var newValue = (bool?)e.NewValue; + base.OnPropertyChanged(change); - switch (newValue) + if (change.Property == IsCheckedProperty) { - case true: - OnChecked(new RoutedEventArgs(IsCheckedChangedEvent)); - break; - case false: - OnUnchecked(new RoutedEventArgs(IsCheckedChangedEvent)); - break; - default: - OnIndeterminate(new RoutedEventArgs(IsCheckedChangedEvent)); - break; + var newValue = change.GetNewValue(); + +#pragma warning disable CS0618 // Type or member is obsolete + switch (newValue) + { + case true: + OnChecked(new RoutedEventArgs(CheckedEvent)); + break; + case false: + OnUnchecked(new RoutedEventArgs(UncheckedEvent)); + break; + default: + OnIndeterminate(new RoutedEventArgs(IndeterminateEvent)); + break; + } +#pragma warning restore CS0618 // Type or member is obsolete + + OnIsCheckedChanged(new RoutedEventArgs(IsCheckedChangedEvent)); } } From 692c0c155dd2f9c8285fb95ede288a18f2ded600 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 24 Nov 2022 23:13:05 +0100 Subject: [PATCH 006/157] Begin refactoring ItemsPresenter. A lot still broken, in particular virtualization is completely removed.`ItemsPresenter` now no longer has an `Items` or `ItemTemplate` property; it detects when it's hosted in an `ItemsControl`. `IItemsPresenter` interface removed. --- .../ControlCatalog/Pages/DialogsPage.xaml.cs | 588 +++--- .../HamburgerMenu/HamburgerMenu.xaml | 4 +- .../Themes/Fluent/ColorView.xaml | 5 +- .../Themes/Simple/ColorView.xaml | 5 +- src/Avalonia.Controls/ComboBox.cs | 2 +- src/Avalonia.Controls/IVirtualizingPanel.cs | 78 - src/Avalonia.Controls/ItemsControl.cs | 12 +- src/Avalonia.Controls/ListBox.cs | 2 +- .../Presenters/CarouselPresenter.cs | 344 ++-- .../Presenters/IItemsPresenter.cs | 18 - .../Presenters/IItemsPresenterHost.cs | 4 +- .../Presenters/ItemContainerSync.cs | 125 -- .../Presenters/ItemVirtualizer.cs | 303 --- .../Presenters/ItemVirtualizerNone.cs | 106 - .../Presenters/ItemVirtualizerSimple.cs | 606 ------ .../Presenters/ItemsPresenter.cs | 187 +- .../Presenters/ItemsPresenterBase.cs | 308 --- .../ItemsPresenterContainerGenerator.cs | 108 + .../Primitives/SelectingItemsControl.cs | 2 +- .../VirtualizingStackPanel.cs | 252 +-- .../Controls/Carousel.xaml | 1 - .../Controls/ComboBox.xaml | 5 +- .../Controls/ContextMenu.xaml | 2 - .../Controls/ItemsControl.xaml | 4 +- .../Controls/ListBox.xaml | 5 +- .../Controls/ManagedFileChooser.xaml | 5 +- src/Avalonia.Themes.Fluent/Controls/Menu.xaml | 4 - .../Controls/MenuFlyoutPresenter.xaml | 2 - .../Controls/MenuItem.xaml | 2 - .../Controls/TabControl.xaml | 2 - .../Controls/TabStrip.xaml | 4 +- .../Controls/TreeView.xaml | 1 - .../Controls/TreeViewItem.xaml | 1 - .../Controls/Carousel.xaml | 1 - .../Controls/ComboBox.xaml | 5 +- .../Controls/ContextMenu.xaml | 2 - .../Controls/ItemsControl.xaml | 2 - .../Controls/ListBox.xaml | 5 +- src/Avalonia.Themes.Simple/Controls/Menu.xaml | 4 - .../Controls/MenuFlyoutPresenter.xaml | 2 - .../Controls/MenuItem.xaml | 2 - .../Controls/TabControl.xaml | 2 - .../Controls/TabStrip.xaml | 2 - .../Controls/TreeView.xaml | 1 - .../Controls/TreeViewItem.xaml | 1 - .../CarouselTests.cs | 1 - .../ComboBoxTests.cs | 1 - .../ItemsControlTests.cs | 4 +- .../ListBoxTests.cs | 52 +- .../ListBoxTests_Multiple.cs | 1 - .../ListBoxTests_Single.cs | 1 - .../Presenters/CarouselPresenterTests.cs | 1464 ++++++------- .../Presenters/ItemsPresenterTests.cs | 370 +--- .../ItemsPresenterTests_Virtualization.cs | 748 +++---- ...emsPresenterTests_Virtualization_Simple.cs | 1822 ++++++++--------- .../Primitives/PopupTests.cs | 5 +- .../Primitives/SelectingItemsControlTests.cs | 2 - .../SelectingItemsControlTests_AutoSelect.cs | 1 - .../SelectingItemsControlTests_Multiple.cs | 1 - .../Primitives/TabStripTests.cs | 1 - .../TreeViewTests.cs | 2 - .../VirtualizingStackPanelTests.cs | 522 ++--- .../AutoDataTemplateBindingHookTest.cs | 1 - tests/Avalonia.UnitTests/TestExtensions.cs | 1 - 64 files changed, 3040 insertions(+), 5086 deletions(-) delete mode 100644 src/Avalonia.Controls/Presenters/IItemsPresenter.cs delete mode 100644 src/Avalonia.Controls/Presenters/ItemContainerSync.cs delete mode 100644 src/Avalonia.Controls/Presenters/ItemVirtualizer.cs delete mode 100644 src/Avalonia.Controls/Presenters/ItemVirtualizerNone.cs delete mode 100644 src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs delete mode 100644 src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs create mode 100644 src/Avalonia.Controls/Presenters/ItemsPresenterContainerGenerator.cs diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs index 67e9ef4e40..41a5b86ebd 100644 --- a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs @@ -24,301 +24,301 @@ namespace ControlCatalog.Pages { this.InitializeComponent(); - var results = this.Get("PickerLastResults"); - var resultsVisible = this.Get("PickerLastResultsVisible"); - var bookmarkContainer = this.Get("BookmarkContainer"); - var openedFileContent = this.Get("OpenedFileContent"); - var openMultiple = this.Get("OpenMultiple"); - - IStorageFolder? lastSelectedDirectory = null; - - List GetFilters() - { - if (this.Get("UseFilters").IsChecked != true) - return new List(); - return new List - { - new FileDialogFilter - { - Name = "Text files (.txt)", Extensions = new List {"txt"} - }, - new FileDialogFilter - { - Name = "All files", - Extensions = new List {"*"} - } - }; - } - - List? GetFileTypes() - { - if (this.Get("UseFilters").IsChecked != true) - return null; - return new List - { - FilePickerFileTypes.All, - FilePickerFileTypes.TextPlain - }; - } - - this.Get