diff --git a/.ncrunch/AppWithoutLifetime.v3.ncrunchproject b/.ncrunch/AppWithoutLifetime.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/AppWithoutLifetime.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Headless.NUnit.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Headless.NUnit.netstandard2.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Headless.NUnit.netstandard2.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Headless.XUnit.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Headless.XUnit.netstandard2.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Headless.XUnit.netstandard2.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf index 92c924f107..5e770a0170 100644 --- a/Avalonia.Desktop.slnf +++ b/Avalonia.Desktop.slnf @@ -39,14 +39,13 @@ "src\\Markup\\Avalonia.Markup.Xaml\\Avalonia.Markup.Xaml.csproj", "src\\Markup\\Avalonia.Markup\\Avalonia.Markup.csproj", "src\\Skia\\Avalonia.Skia\\Avalonia.Skia.csproj", - "src\\tools\\Avalonia.Generators\\Avalonia.Generators.csproj", - "src\\tools\\Avalonia.Generators\\Avalonia.Generators.csproj", - "src\\tools\\DevAnalyzers\\DevAnalyzers.csproj", - "src\\tools\\DevGenerators\\DevGenerators.csproj", - "src\\tools\\PublicAnalyzers\\Avalonia.Analyzers.csproj", "src\\Windows\\Avalonia.Direct2D1\\Avalonia.Direct2D1.csproj", "src\\Windows\\Avalonia.Win32.Interop\\Avalonia.Win32.Interop.csproj", "src\\Windows\\Avalonia.Win32\\Avalonia.Win32.csproj", + "src\\tools\\Avalonia.Analyzers\\Avalonia.Analyzers.csproj", + "src\\tools\\Avalonia.Generators\\Avalonia.Generators.csproj", + "src\\tools\\DevAnalyzers\\DevAnalyzers.csproj", + "src\\tools\\DevGenerators\\DevGenerators.csproj", "tests\\Avalonia.Base.UnitTests\\Avalonia.Base.UnitTests.csproj", "tests\\Avalonia.Benchmarks\\Avalonia.Benchmarks.csproj", "tests\\Avalonia.Controls.DataGrid.UnitTests\\Avalonia.Controls.DataGrid.UnitTests.csproj", @@ -66,4 +65,4 @@ "tests\\Avalonia.UnitTests\\Avalonia.UnitTests.csproj" ] } -} +} \ No newline at end of file diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj index 412251bc9c..8f1b39ae12 100644 --- a/packages/Avalonia/Avalonia.csproj +++ b/packages/Avalonia/Avalonia.csproj @@ -5,7 +5,7 @@ - + all diff --git a/samples/ControlCatalog/Pages/ColorPickerPage.xaml b/samples/ControlCatalog/Pages/ColorPickerPage.xaml index b759720cf2..25fffabfd2 100644 --- a/samples/ControlCatalog/Pages/ColorPickerPage.xaml +++ b/samples/ControlCatalog/Pages/ColorPickerPage.xaml @@ -103,7 +103,8 @@ HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />--> + HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" + Margin="0,2,0,0" /> diff --git a/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs b/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs index 7fb5bec589..aef82768c8 100644 --- a/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Linq; using System.Reflection; using Avalonia.Controls; @@ -23,7 +22,7 @@ namespace ControlCatalog.Pages $"Text was dragged {++textCount} times"), DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link); SetupDnd("Custom", d => d.Set(CustomFormat, "Test123"), DragDropEffects.Move); - SetupDnd("Files", d => d.Set(DataFormats.Files, new[] { Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName }), DragDropEffects.Copy); + SetupDnd("Files", async d => d.Set(DataFormats.Files, new[] { await (VisualRoot as TopLevel)!.StorageProvider.TryGetFileFromPathAsync(Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName) }), DragDropEffects.Copy); } void SetupDnd(string suffix, Action factory, DragDropEffects effects) @@ -99,7 +98,7 @@ namespace ControlCatalog.Pages { if (item is IStorageFile file) { - var content = await DialogsPage.ReadTextFromFile(file, 1000); + var content = await DialogsPage.ReadTextFromFile(file, 500); contentStr += $"File {item.Name}:{Environment.NewLine}{content}{Environment.NewLine}{Environment.NewLine}"; } else if (item is IStorageFolder folder) diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml b/samples/ControlCatalog/Pages/TabControlPage.xaml index 3a2464e9fd..1faa74c1ce 100644 --- a/samples/ControlCatalog/Pages/TabControlPage.xaml +++ b/samples/ControlCatalog/Pages/TabControlPage.xaml @@ -4,7 +4,27 @@ xmlns="https://github.com/avaloniaui" xmlns:viewModels="using:ControlCatalog.ViewModels" x:DataType="viewModels:TabControlPageViewModel"> - + + + + + + - + - + + + + + + --> + diff --git a/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPreviewer.xaml b/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPreviewer.xaml index e05fa5a907..fabc5d0349 100644 --- a/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPreviewer.xaml +++ b/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPreviewer.xaml @@ -8,7 +8,9 @@ - + + + @@ -21,7 +23,6 @@ Height="{StaticResource ColorPreviewerAccentSectionHeight}" Width="{StaticResource ColorPreviewerAccentSectionWidth}" ColumnDefinitions="*,*" - Margin="0,0,-10,0" VerticalAlignment="Center"> + CornerRadius="{TemplateBinding CornerRadius}"> @@ -82,8 +80,7 @@ + VerticalAlignment="Stretch"> diff --git a/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml b/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml index acd2c7ff15..8793467b36 100644 --- a/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml +++ b/src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml @@ -360,8 +360,8 @@ - + + + + diff --git a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPicker.xaml b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPicker.xaml index ff4e1d93a8..d9ba8bb9d2 100644 --- a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPicker.xaml +++ b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPicker.xaml @@ -112,8 +112,8 @@ - + @@ -501,6 +501,23 @@ + + + diff --git a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml index a39dd91f52..9e123b2a1f 100644 --- a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml +++ b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml @@ -8,7 +8,9 @@ - + + + @@ -21,7 +23,6 @@ Height="{StaticResource ColorPreviewerAccentSectionHeight}" Width="{StaticResource ColorPreviewerAccentSectionWidth}" ColumnDefinitions="*,*" - Margin="0,0,-10,0" VerticalAlignment="Center"> + CornerRadius="{TemplateBinding CornerRadius}"> @@ -82,8 +80,7 @@ + VerticalAlignment="Stretch"> diff --git a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorView.xaml b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorView.xaml index a26d3179b5..d4f02933f2 100644 --- a/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorView.xaml +++ b/src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorView.xaml @@ -322,8 +322,8 @@ - + + + + diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index a55a47fa53..bfcd4750e3 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -3958,7 +3958,7 @@ namespace Avalonia.Controls { bool focusLeftDataGrid = true; bool dataGridWillReceiveRoutedEvent = true; - Visual focusedObject = FocusManager.Instance.Current as Visual; + Visual focusedObject = FocusManager.GetFocusManager(this)?.GetFocusedElement() as Visual; DataGridColumn editingColumn = null; while (focusedObject != null) @@ -4865,7 +4865,8 @@ namespace Avalonia.Controls if (!ctrl) { // If Enter was used by a TextBox, we shouldn't handle the key - if (FocusManager.Instance.Current is TextBox focusedTextBox && focusedTextBox.AcceptsReturn) + if (FocusManager.GetFocusManager(this)?.GetFocusedElement() is TextBox focusedTextBox + && focusedTextBox.AcceptsReturn) { return false; } diff --git a/src/Avalonia.Controls.ItemsRepeater/Controls/RepeaterLayoutContext.cs b/src/Avalonia.Controls.ItemsRepeater/Controls/RepeaterLayoutContext.cs index 49c8b9ff92..d03949c1c2 100644 --- a/src/Avalonia.Controls.ItemsRepeater/Controls/RepeaterLayoutContext.cs +++ b/src/Avalonia.Controls.ItemsRepeater/Controls/RepeaterLayoutContext.cs @@ -53,8 +53,8 @@ namespace Avalonia.Controls { return _owner.GetElementImpl( index, - options.HasAllFlags(ElementRealizationOptions.ForceCreate), - options.HasAllFlags(ElementRealizationOptions.SuppressAutoRecycle)); + options.HasFlag(ElementRealizationOptions.ForceCreate), + options.HasFlag(ElementRealizationOptions.SuppressAutoRecycle)); } protected override object GetItemAtCore(int index) => _owner.ItemsSourceView!.GetAt(index)!; diff --git a/src/Avalonia.Controls.ItemsRepeater/Controls/ViewManager.cs b/src/Avalonia.Controls.ItemsRepeater/Controls/ViewManager.cs index 6b9d7934bf..674389d77c 100644 --- a/src/Avalonia.Controls.ItemsRepeater/Controls/ViewManager.cs +++ b/src/Avalonia.Controls.ItemsRepeater/Controls/ViewManager.cs @@ -695,7 +695,7 @@ namespace Avalonia.Controls { Control? focusedElement = null; - if (FocusManager.Instance?.Current is Visual child) + if (TopLevel.GetTopLevel(_owner)?.FocusManager?.GetFocusedElement() is Visual child) { var parent = child.GetVisualParent(); var owner = _owner; diff --git a/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs index 20711eecbc..d0b894101f 100644 --- a/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs +++ b/src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs @@ -762,7 +762,7 @@ namespace Avalonia.Controls /// otherwise, false. protected bool HasFocus() { - Visual? focused = FocusManager.Instance?.Current as Visual; + Visual? focused = FocusManager.GetFocusManager(this)?.GetFocusedElement() as Visual; while (focused != null) { diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs index d04dfec3e8..c55bd0f3e5 100644 --- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs @@ -151,7 +151,7 @@ namespace Avalonia.Automation.Peers protected override bool HasKeyboardFocusCore() => Owner.IsFocused; protected override bool IsContentElementCore() => true; protected override bool IsControlElementCore() => true; - protected override bool IsEnabledCore() => Owner.IsEnabled; + protected override bool IsEnabledCore() => Owner.IsEffectivelyEnabled; protected override bool IsKeyboardFocusableCore() => Owner.Focusable; protected override void SetFocusCore() => Owner.Focus(); diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 48761ca8b8..3f1753a4d3 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -14,6 +14,7 @@ + @@ -22,5 +23,6 @@ + diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs index f48d7a7cc1..d8c31fc477 100644 --- a/src/Avalonia.Controls/Button.cs +++ b/src/Avalonia.Controls/Button.cs @@ -34,8 +34,8 @@ namespace Avalonia.Controls [PseudoClasses(pcFlyoutOpen, pcPressed)] public class Button : ContentControl, ICommandSource, IClickableControl { - protected const string pcPressed = ":pressed"; - protected const string pcFlyoutOpen = ":flyout-open"; + private const string pcPressed = ":pressed"; + private const string pcFlyoutOpen = ":flyout-open"; /// /// Defines the property. diff --git a/src/Avalonia.Controls/Calendar/Calendar.cs b/src/Avalonia.Controls/Calendar/Calendar.cs index 10aadfa759..6468d0b4e8 100644 --- a/src/Avalonia.Controls/Calendar/Calendar.cs +++ b/src/Avalonia.Controls/Calendar/Calendar.cs @@ -1567,7 +1567,7 @@ namespace Avalonia.Controls base.OnPointerReleased(e); if (!HasFocusInternal && e.InitialPressMouseButton == MouseButton.Left) { - FocusManager.Instance?.Focus(this); + Focus(); } } diff --git a/src/Avalonia.Controls/Calendar/CalendarButton.cs b/src/Avalonia.Controls/Calendar/CalendarButton.cs index d8672cbf18..b35298b101 100644 --- a/src/Avalonia.Controls/Calendar/CalendarButton.cs +++ b/src/Avalonia.Controls/Calendar/CalendarButton.cs @@ -39,7 +39,7 @@ namespace Avalonia.Controls.Primitives public CalendarButton() : base() { - Content = DateTimeHelper.GetCurrentDateFormat().AbbreviatedMonthNames[0]; + SetCurrentValue(ContentProperty, DateTimeHelper.GetCurrentDateFormat().AbbreviatedMonthNames[0]); } /// diff --git a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs b/src/Avalonia.Controls/Calendar/CalendarDayButton.cs index 3d0befdba7..ea3ca8e8fc 100644 --- a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs +++ b/src/Avalonia.Controls/Calendar/CalendarDayButton.cs @@ -34,7 +34,7 @@ namespace Avalonia.Controls.Primitives : base() { //Focusable = false; - Content = DefaultContent.ToString(CultureInfo.CurrentCulture); + SetCurrentValue(ContentProperty, DefaultContent.ToString(CultureInfo.CurrentCulture)); } /// diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs index 2e3f1f96ce..e81ed8072e 100644 --- a/src/Avalonia.Controls/Calendar/CalendarItem.cs +++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs @@ -171,7 +171,7 @@ namespace Avalonia.Controls.Primitives var childCount = Calendar.RowsPerMonth + Calendar.RowsPerMonth * Calendar.ColumnsPerMonth; using var children = new PooledList(childCount); - for (int i = 0; i < Calendar.RowsPerMonth; i++) + for (int i = 0; i < Calendar.ColumnsPerMonth; i++) { if (DayTitleTemplate?.Build() is Control cell) { diff --git a/src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs b/src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs index 90153d3293..679ac4a853 100644 --- a/src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs +++ b/src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs @@ -26,8 +26,8 @@ namespace Avalonia.Controls [PseudoClasses(pcFlyoutOpen, pcPressed)] public partial class CalendarDatePicker : TemplatedControl { - protected const string pcPressed = ":pressed"; - protected const string pcFlyoutOpen = ":flyout-open"; + private const string pcPressed = ":pressed"; + private const string pcFlyoutOpen = ":flyout-open"; private const string ElementTextBox = "PART_TextBox"; private const string ElementButton = "PART_Button"; diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index f41c00662d..926cd5d58e 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -21,8 +21,9 @@ namespace Avalonia.Controls [PseudoClasses(pcDropdownOpen, pcPressed)] public class ComboBox : SelectingItemsControl { - public const string pcDropdownOpen = ":dropdownopen"; - public const string pcPressed = ":pressed"; + internal const string pcDropdownOpen = ":dropdownopen"; + internal const string pcPressed = ":pressed"; + /// /// The default value for the property. /// @@ -164,7 +165,7 @@ namespace Avalonia.Controls UpdateSelectionBoxItem(SelectedItem); } - public override void InvalidateMirrorTransform() + protected internal override void InvalidateMirrorTransform() { base.InvalidateMirrorTransform(); UpdateFlowDirection(); @@ -230,8 +231,7 @@ namespace Avalonia.Controls var firstChild = Presenter?.Panel?.Children.FirstOrDefault(c => CanFocus(c)); if (firstChild != null) { - FocusManager.Instance?.Focus(firstChild, NavigationMethod.Directional); - e.Handled = true; + e.Handled = firstChild.Focus(NavigationMethod.Directional); } } } diff --git a/src/Avalonia.Controls/ContentControl.cs b/src/Avalonia.Controls/ContentControl.cs index f30920ed2e..867dca2be1 100644 --- a/src/Avalonia.Controls/ContentControl.cs +++ b/src/Avalonia.Controls/ContentControl.cs @@ -13,7 +13,7 @@ namespace Avalonia.Controls /// /// Displays according to an . /// - [TemplatePart("PART_ContentPresenter", typeof(IContentPresenter))] + [TemplatePart("PART_ContentPresenter", typeof(ContentPresenter))] public class ContentControl : TemplatedControl, IContentControl, IContentPresenterHost { /// @@ -68,7 +68,7 @@ namespace Avalonia.Controls /// /// Gets the presenter from the control's template. /// - public IContentPresenter? Presenter + public ContentPresenter? Presenter { get; private set; @@ -96,16 +96,16 @@ namespace Avalonia.Controls IAvaloniaList IContentPresenterHost.LogicalChildren => LogicalChildren; /// - bool IContentPresenterHost.RegisterContentPresenter(IContentPresenter presenter) + bool IContentPresenterHost.RegisterContentPresenter(ContentPresenter presenter) { return RegisterContentPresenter(presenter); } /// - /// Called when an is registered with the control. + /// Called when an is registered with the control. /// /// The presenter. - protected virtual bool RegisterContentPresenter(IContentPresenter presenter) + protected virtual bool RegisterContentPresenter(ContentPresenter presenter) { if (presenter.Name == "PART_ContentPresenter") { @@ -116,19 +116,14 @@ namespace Avalonia.Controls return false; } - protected virtual void ContentChanged(AvaloniaPropertyChangedEventArgs e) + private void ContentChanged(AvaloniaPropertyChangedEventArgs e) { - UpdateLogicalTree(e.OldValue, e.NewValue); - } - - protected void UpdateLogicalTree(object? toRemove, object? toAdd) - { - if (toRemove is ILogical oldChild) + if (e.OldValue is ILogical oldChild) { LogicalChildren.Remove(oldChild); } - if (toAdd is ILogical newChild) + if (e.NewValue is ILogical newChild) { LogicalChildren.Add(newChild); } diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index 97a8c6fe97..a9d8e4c9c7 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/src/Avalonia.Controls/ContextMenu.cs @@ -285,7 +285,7 @@ namespace Avalonia.Controls } } - void ISetterValue.Initialize(ISetter setter) + void ISetterValue.Initialize(SetterBase setter) { // ContextMenu can be assigned to the ContextMenu property in a setter. This overrides // the behavior defined in Control which requires controls to be wrapped in a