diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml
index c7a75f5a70..1c8c38d3e5 100644
--- a/samples/ControlCatalog/App.xaml
+++ b/samples/ControlCatalog/App.xaml
@@ -4,14 +4,14 @@
diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs
index 3f1ec289d1..b0fbcc76d2 100644
--- a/samples/ControlCatalog/App.xaml.cs
+++ b/samples/ControlCatalog/App.xaml.cs
@@ -67,9 +67,9 @@ namespace ControlCatalog
public override void Initialize()
{
- AvaloniaXamlLoader.Load(this);
-
Styles.Insert(0, FluentDark);
+
+ AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index af95e3c356..efc90357ed 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -1,9 +1,7 @@
+ x:Class="ControlCatalog.MainView">
diff --git a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml
index 304782dbf9..392ccb57c3 100644
--- a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml
+++ b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml
@@ -43,7 +43,7 @@
-
+
diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml
index f4d81418ac..edf3d41bf5 100644
--- a/samples/ControlCatalog/Pages/ListBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml
@@ -11,8 +11,7 @@
Spacing="16">
(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
- SelectedItems = new ObservableCollection();
-
- AddItemCommand = ReactiveCommand.Create(() => Items.Add(GenerateItem()));
-
- RemoveItemCommand = ReactiveCommand.Create(() =>
- {
- while (SelectedItems.Count > 0)
- {
- Items.Remove(SelectedItems[0]);
- }
- });
-
- SelectRandomItemCommand = ReactiveCommand.Create(() =>
- {
- var random = new Random();
-
- SelectedItem = Items[random.Next(Items.Count - 1)];
- });
- }
-
- public ObservableCollection Items { get; }
-
- private string _selectedItem;
-
- public string SelectedItem
- {
- get { return _selectedItem; }
- set { this.RaiseAndSetIfChanged(ref _selectedItem, value); }
- }
-
-
- public ObservableCollection SelectedItems { get; }
-
- public ReactiveCommand AddItemCommand { get; }
-
- public ReactiveCommand RemoveItemCommand { get; }
-
- public ReactiveCommand SelectRandomItemCommand { get; }
-
- public SelectionMode SelectionMode
- {
- get => _selectionMode;
- set
- {
- SelectedItems.Clear();
- this.RaiseAndSetIfChanged(ref _selectionMode, value);
- }
- }
-
- private string GenerateItem() => $"Item {_counter++.ToString()}";
- }
}
}
diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs
index d775eb9635..c39f414b44 100644
--- a/samples/ControlCatalog/Pages/ScreenPage.cs
+++ b/samples/ControlCatalog/Pages/ScreenPage.cs
@@ -29,7 +29,8 @@ namespace ControlCatalog.Pages
var screens = w.Screens.All;
var scaling = ((IRenderRoot)w).RenderScaling;
- Pen p = new Pen(Brushes.Black);
+ var drawBrush = Brushes.Green;
+ Pen p = new Pen(drawBrush);
if (screens != null)
foreach (Screen screen in screens)
{
@@ -53,19 +54,19 @@ namespace ControlCatalog.Pages
};
text.Text = $"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height), text);
text.Text = $"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
text.Text = $"Scaling: {screen.PixelDensity * 100}%";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text);
text.Text = $"Primary: {screen.Primary}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text);
text.Text = $"Current: {screen.Equals(w.Screens.ScreenFromBounds(new PixelRect(w.Position, PixelSize.FromSize(w.Bounds.Size, scaling))))}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
}
context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10, w.Bounds.Width / 10, w.Bounds.Height / 10));
diff --git a/samples/ControlCatalog/Pages/TextBlockPage.xaml b/samples/ControlCatalog/Pages/TextBlockPage.xaml
index 4b8edcf98c..4a1c196917 100644
--- a/samples/ControlCatalog/Pages/TextBlockPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBlockPage.xaml
@@ -12,7 +12,7 @@
@@ -49,7 +49,7 @@
diff --git a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
new file mode 100644
index 0000000000..6bdb5c0103
--- /dev/null
+++ b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reactive;
+using Avalonia.Controls;
+using ReactiveUI;
+
+namespace ControlCatalog.ViewModels
+{
+ public class ListBoxPageViewModel : ReactiveObject
+ {
+ private int _counter;
+ private SelectionMode _selectionMode;
+
+ public ListBoxPageViewModel()
+ {
+ Items = new ObservableCollection(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
+ Selection = new SelectionModel();
+ Selection.Select(1);
+
+ AddItemCommand = ReactiveCommand.Create(() => Items.Add(GenerateItem()));
+
+ RemoveItemCommand = ReactiveCommand.Create(() =>
+ {
+ while (Selection.SelectedItems.Count > 0)
+ {
+ Items.Remove((string)Selection.SelectedItems.First());
+ }
+ });
+
+ SelectRandomItemCommand = ReactiveCommand.Create(() =>
+ {
+ var random = new Random();
+
+ using (Selection.Update())
+ {
+ Selection.ClearSelection();
+ Selection.Select(random.Next(Items.Count - 1));
+ }
+ });
+ }
+
+ public ObservableCollection Items { get; }
+
+ public SelectionModel Selection { get; }
+
+ public ReactiveCommand AddItemCommand { get; }
+
+ public ReactiveCommand RemoveItemCommand { get; }
+
+ public ReactiveCommand SelectRandomItemCommand { get; }
+
+ public SelectionMode SelectionMode
+ {
+ get => _selectionMode;
+ set
+ {
+ Selection.ClearSelection();
+ this.RaiseAndSetIfChanged(ref _selectionMode, value);
+ }
+ }
+
+ private string GenerateItem() => $"Item {_counter++.ToString()}";
+ }
+}
diff --git a/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs b/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
index 31527ccb16..eec4615736 100644
--- a/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
+++ b/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
@@ -356,10 +356,17 @@ namespace Avalonia.Controls
}
if (MonthVisible)
+ {
_monthSelector.SelectedValue = dt.Month;
-
+ _monthSelector.FormatDate = dt.Date;
+ }
+
if (YearVisible)
+ {
_yearSelector.SelectedValue = dt.Year;
+ _yearSelector.FormatDate = dt.Date;
+ }
+
_suppressUpdateSelection = false;
SetInitialFocus();
diff --git a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs b/src/Avalonia.Controls/Repeater/ItemsSourceView.cs
index ecf8abc13f..def9301e2d 100644
--- a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs
+++ b/src/Avalonia.Controls/Repeater/ItemsSourceView.cs
@@ -25,7 +25,6 @@ namespace Avalonia.Controls
{
private readonly IList _inner;
private INotifyCollectionChanged _notifyCollectionChanged;
- private int _cachedSize = -1;
///
/// Initializes a new instance of the ItemsSourceView class for the specified data source.
@@ -54,18 +53,7 @@ namespace Avalonia.Controls
///
/// Gets the number of items in the collection.
///
- public int Count
- {
- get
- {
- if (_cachedSize == -1)
- {
- _cachedSize = _inner.Count;
- }
-
- return _cachedSize;
- }
- }
+ public int Count => _inner.Count;
///
/// Gets a value that indicates whether the items source can provide a unique key for each item.
@@ -126,7 +114,6 @@ namespace Avalonia.Controls
protected void OnItemsSourceChanged(NotifyCollectionChangedEventArgs args)
{
- _cachedSize = _inner.Count;
CollectionChanged?.Invoke(this, args);
}
diff --git a/src/Avalonia.Controls/Utils/SelectedItemsSync.cs b/src/Avalonia.Controls/Utils/SelectedItemsSync.cs
index c127771990..91cef9fe64 100644
--- a/src/Avalonia.Controls/Utils/SelectedItemsSync.cs
+++ b/src/Avalonia.Controls/Utils/SelectedItemsSync.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Specialized;
+using System.ComponentModel;
using System.Linq;
using Avalonia.Collections;
@@ -16,6 +17,7 @@ namespace Avalonia.Controls.Utils
private IList? _items;
private bool _updatingItems;
private bool _updatingModel;
+ private bool _initializeOnSourceAssignment;
public SelectedItemsSync(ISelectionModel model)
{
@@ -63,10 +65,18 @@ namespace Avalonia.Controls.Utils
_updatingModel = true;
_items = items;
- using (Model.Update())
+ if (Model.Source is object)
{
- Model.ClearSelection();
- Add(items);
+ using (Model.Update())
+ {
+ Model.ClearSelection();
+ Add(items);
+ }
+ }
+ else if (!_initializeOnSourceAssignment)
+ {
+ Model.PropertyChanged += SelectionModelPropertyChanged;
+ _initializeOnSourceAssignment = true;
}
if (_items is INotifyCollectionChanged incc2)
@@ -86,9 +96,11 @@ namespace Avalonia.Controls.Utils
if (_items != null)
{
+ Model.PropertyChanged -= SelectionModelPropertyChanged;
Model.SelectionChanged -= SelectionModelSelectionChanged;
Model = model;
Model.SelectionChanged += SelectionModelSelectionChanged;
+ _initializeOnSourceAssignment = false;
try
{
@@ -175,6 +187,25 @@ namespace Avalonia.Controls.Utils
}
}
+ private void SelectionModelPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (_initializeOnSourceAssignment &&
+ _items != null &&
+ e.PropertyName == nameof(SelectionModel.Source))
+ {
+ try
+ {
+ _updatingModel = true;
+ Add(_items);
+ _initializeOnSourceAssignment = false;
+ }
+ finally
+ {
+ _updatingModel = false;
+ }
+ }
+ }
+
private void SelectionModelSelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e)
{
if (_updatingModel)
diff --git a/src/Avalonia.Dialogs/ManagedFileChooser.xaml b/src/Avalonia.Dialogs/ManagedFileChooser.xaml
index 8a0451f982..227cc1afc0 100644
--- a/src/Avalonia.Dialogs/ManagedFileChooser.xaml
+++ b/src/Avalonia.Dialogs/ManagedFileChooser.xaml
@@ -66,7 +66,7 @@
-
+ DockPanel.Dock="Left" Focusable="False">
diff --git a/src/Avalonia.Themes.Default/Accents/BaseDark.xaml b/src/Avalonia.Themes.Default/Accents/BaseDark.xaml
index ffe3e92202..44dfb9ea48 100644
--- a/src/Avalonia.Themes.Default/Accents/BaseDark.xaml
+++ b/src/Avalonia.Themes.Default/Accents/BaseDark.xaml
@@ -58,6 +58,11 @@
+
+
+
+
+
1,1,1,1
0.5
diff --git a/src/Avalonia.Themes.Default/Accents/BaseLight.xaml b/src/Avalonia.Themes.Default/Accents/BaseLight.xaml
index c0e5f47eed..9ed3207235 100644
--- a/src/Avalonia.Themes.Default/Accents/BaseLight.xaml
+++ b/src/Avalonia.Themes.Default/Accents/BaseLight.xaml
@@ -61,6 +61,11 @@
+
+
+
+
+
1
0.5
diff --git a/src/Avalonia.Themes.Default/DatePicker.xaml b/src/Avalonia.Themes.Default/DatePicker.xaml
new file mode 100644
index 0000000000..da878c88e2
--- /dev/null
+++ b/src/Avalonia.Themes.Default/DatePicker.xaml
@@ -0,0 +1,334 @@
+
+
+
+
+ 0,0,0,4
+ 40
+ 40
+ 41
+ 296
+ 456
+ 0,3,0,6
+ 9,3,0,6
+ 0,3,0,6
+ 9,3,0,6
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml b/src/Avalonia.Themes.Default/DefaultTheme.xaml
index 4e63d1d223..e5b654b490 100644
--- a/src/Avalonia.Themes.Default/DefaultTheme.xaml
+++ b/src/Avalonia.Themes.Default/DefaultTheme.xaml
@@ -55,4 +55,7 @@
+
+
+
diff --git a/src/Avalonia.Themes.Default/SplitView.xaml b/src/Avalonia.Themes.Default/SplitView.xaml
new file mode 100644
index 0000000000..4a9a7be164
--- /dev/null
+++ b/src/Avalonia.Themes.Default/SplitView.xaml
@@ -0,0 +1,219 @@
+
+
+
+ 320
+ 48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/TabItem.xaml b/src/Avalonia.Themes.Default/TabItem.xaml
index 92482a564c..6e344ce58e 100644
--- a/src/Avalonia.Themes.Default/TabItem.xaml
+++ b/src/Avalonia.Themes.Default/TabItem.xaml
@@ -2,7 +2,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/ToggleSwitch.xaml b/src/Avalonia.Themes.Default/ToggleSwitch.xaml
index ded121f5f6..5c0a3b99f3 100644
--- a/src/Avalonia.Themes.Default/ToggleSwitch.xaml
+++ b/src/Avalonia.Themes.Default/ToggleSwitch.xaml
@@ -6,8 +6,40 @@
6
6
154
- 20
- 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -148,16 +180,13 @@
-
-
@@ -264,10 +289,6 @@
-
-
diff --git a/src/Avalonia.Themes.Fluent/Accents/Base.xaml b/src/Avalonia.Themes.Fluent/Accents/Base.xaml
index 8358297f8b..46488c1c57 100644
--- a/src/Avalonia.Themes.Fluent/Accents/Base.xaml
+++ b/src/Avalonia.Themes.Fluent/Accents/Base.xaml
@@ -6,12 +6,12 @@
#FFF0F0F0
#FF000000
- #FF6D6D6D
- #FF3399FF
- #FFFFFFFF
- #FF0066CC
- #FFFFFFFF
- #FF000000
+ #FF6D6D6D
+ #FF3399FF
+ #FFFFFFFF
+ #FF0066CC
+ #FFFFFFFF
+ #FF000000
avares://Avalonia.Themes.Fluent/Assets#Roboto
14
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
index 653e4733cb..4d21068492 100644
--- a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
@@ -437,6 +437,15 @@
+
+
+
+
+
+
+
+
+
1
diff --git a/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml b/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
index 6d83674c43..532826c500 100644
--- a/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
+++ b/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
@@ -52,13 +52,12 @@
diff --git a/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
index 62d1653de7..82265ea282 100644
--- a/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
+++ b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
@@ -8,7 +8,11 @@
+ AllowSpin="False">
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/CalendarButton.xaml b/src/Avalonia.Themes.Fluent/CalendarButton.xaml
index 87082ef21e..ca538e4b0a 100644
--- a/src/Avalonia.Themes.Fluent/CalendarButton.xaml
+++ b/src/Avalonia.Themes.Fluent/CalendarButton.xaml
@@ -67,7 +67,7 @@
-
+
diff --git a/src/Avalonia.Themes.Fluent/MenuItem.xaml b/src/Avalonia.Themes.Fluent/MenuItem.xaml
index 746a315ce0..2115319c3c 100644
--- a/src/Avalonia.Themes.Fluent/MenuItem.xaml
+++ b/src/Avalonia.Themes.Fluent/MenuItem.xaml
@@ -50,7 +50,6 @@