diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 7956ee6169..af2d093bc7 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -29,7 +29,8 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
-
+
+
-
+
+
diff --git a/samples/ControlCatalog/Pages/DatePickerPage.xaml b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
similarity index 75%
rename from samples/ControlCatalog/Pages/DatePickerPage.xaml
rename to samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
index 30d5a7506f..107472105a 100644
--- a/samples/ControlCatalog/Pages/DatePickerPage.xaml
+++ b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
@@ -1,8 +1,8 @@
+ x:Class="ControlCatalog.Pages.CalendarDatePickerPage">
- DatePicker
+ CalendarDatePicker
A control for selecting dates with a calendar drop-down
-
-
-
-
-
-
-
+
diff --git a/samples/ControlCatalog/Pages/DatePickerPage.xaml.cs b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
similarity index 57%
rename from samples/ControlCatalog/Pages/DatePickerPage.xaml.cs
rename to samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
index ef01887c9e..95bdeb363a 100644
--- a/samples/ControlCatalog/Pages/DatePickerPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
@@ -4,17 +4,17 @@ using System;
namespace ControlCatalog.Pages
{
- public class DatePickerPage : UserControl
+ public class CalendarDatePickerPage : UserControl
{
- public DatePickerPage()
+ public CalendarDatePickerPage()
{
InitializeComponent();
- var dp1 = this.FindControl("DatePicker1");
- var dp2 = this.FindControl("DatePicker2");
- var dp3 = this.FindControl("DatePicker3");
- var dp4 = this.FindControl("DatePicker4");
- var dp5 = this.FindControl("DatePicker5");
+ var dp1 = this.FindControl("DatePicker1");
+ var dp2 = this.FindControl("DatePicker2");
+ var dp3 = this.FindControl("DatePicker3");
+ var dp4 = this.FindControl("DatePicker4");
+ var dp5 = this.FindControl("DatePicker5");
dp1.SelectedDate = DateTime.Today;
dp2.SelectedDate = DateTime.Today.AddDays(10);
diff --git a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
index e605a92da0..0d7e5da17f 100644
--- a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
+++ b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
@@ -50,22 +50,22 @@
Text:
-
+
Minimum:
+ CultureInfo="{Binding #upDown.CultureInfo}" VerticalAlignment="Center" Margin="2" HorizontalAlignment="Center"/>
Maximum:
+ CultureInfo="{Binding #upDown.CultureInfo}" VerticalAlignment="Center" Margin="2" HorizontalAlignment="Center"/>
Increment:
+ Margin="2" HorizontalAlignment="Center"/>
Value:
+ Margin="2" HorizontalAlignment="Center"/>
@@ -73,7 +73,7 @@
Usage of NumericUpDown:
diff --git a/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
index 84ef0fb695..8fc2a7b77c 100644
--- a/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
+++ b/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
@@ -12,7 +12,7 @@ namespace Avalonia.Data.Core.Plugins
public class InpcPropertyAccessorPlugin : IPropertyAccessorPlugin
{
///
- public bool Match(object obj, string propertyName) => true;
+ public bool Match(object obj, string propertyName) => GetPropertyWithName(obj.GetType(), propertyName) != null;
///
/// Starts monitoring the value of a property on an object.
@@ -30,10 +30,7 @@ namespace Avalonia.Data.Core.Plugins
reference.TryGetTarget(out object instance);
- const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance;
-
- var p = instance.GetType().GetProperty(propertyName, bindingFlags);
+ var p = GetPropertyWithName(instance.GetType(), propertyName);
if (p != null)
{
@@ -47,6 +44,14 @@ namespace Avalonia.Data.Core.Plugins
}
}
+ private static PropertyInfo GetPropertyWithName(Type type, string propertyName)
+ {
+ const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public |
+ BindingFlags.Static | BindingFlags.Instance;
+
+ return type.GetProperty(propertyName, bindingFlags);
+ }
+
private class Accessor : PropertyAccessorBase, IWeakSubscriber
{
private readonly WeakReference
- public event EventHandler DateValidationError;
+ public event EventHandler DateValidationError;
///
/// Occurs when the
- ///
+ ///
/// property is changed.
///
public event EventHandler SelectedDateChanged;
- static DatePicker()
+ static CalendarDatePicker()
{
- FocusableProperty.OverrideDefaultValue(true);
-
- DisplayDateProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateChanged(e));
- DisplayDateStartProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateStartChanged(e));
- DisplayDateEndProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateEndChanged(e));
- IsDropDownOpenProperty.Changed.AddClassHandler((x,e) => x.OnIsDropDownOpenChanged(e));
- SelectedDateProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateChanged(e));
- SelectedDateFormatProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateFormatChanged(e));
- CustomDateFormatStringProperty.Changed.AddClassHandler((x,e) => x.OnCustomDateFormatStringChanged(e));
- TextProperty.Changed.AddClassHandler((x,e) => x.OnTextChanged(e));
+ FocusableProperty.OverrideDefaultValue(true);
+
+ DisplayDateProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateChanged(e));
+ DisplayDateStartProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateStartChanged(e));
+ DisplayDateEndProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateEndChanged(e));
+ IsDropDownOpenProperty.Changed.AddClassHandler((x,e) => x.OnIsDropDownOpenChanged(e));
+ SelectedDateProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateChanged(e));
+ SelectedDateFormatProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateFormatChanged(e));
+ CustomDateFormatStringProperty.Changed.AddClassHandler((x,e) => x.OnCustomDateFormatStringChanged(e));
+ TextProperty.Changed.AddClassHandler((x,e) => x.OnTextChanged(e));
}
///
/// Initializes a new instance of the
/// class.
///
- public DatePicker()
+ public CalendarDatePicker()
{
FirstDayOfWeek = DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek;
_defaultText = string.Empty;
@@ -662,12 +662,12 @@ namespace Avalonia.Controls
// change is coming from the Calendar UI itself, so, we
// shouldn't change the DisplayDate since it will automatically
// be changed by the Calendar
- if ((day.Month != DisplayDate.Month || day.Year != DisplayDate.Year) && (_calendar == null || !_calendar.DatePickerDisplayDateFlag))
+ if ((day.Month != DisplayDate.Month || day.Year != DisplayDate.Year) && (_calendar == null || !_calendar.CalendarDatePickerDisplayDateFlag))
{
DisplayDate = day;
}
if(_calendar != null)
- _calendar.DatePickerDisplayDateFlag = false;
+ _calendar.CalendarDatePickerDisplayDateFlag = false;
}
else
{
@@ -707,7 +707,7 @@ namespace Avalonia.Controls
}
private void OnCustomDateFormatStringChanged(AvaloniaPropertyChangedEventArgs e)
{
- if(SelectedDateFormat == DatePickerFormat.Custom)
+ if(SelectedDateFormat == CalendarDatePickerFormat.Custom)
{
OnDateFormatChanged();
}
@@ -752,15 +752,15 @@ namespace Avalonia.Controls
///
/// Raises the
- ///
+ ///
/// event.
///
///
/// A
- ///
+ ///
/// that contains the event data.
///
- protected virtual void OnDateValidationError(DatePickerDateValidationErrorEventArgs e)
+ protected virtual void OnDateValidationError(CalendarDatePickerDateValidationErrorEventArgs e)
{
DateValidationError?.Invoke(this, e);
}
@@ -959,7 +959,7 @@ namespace Avalonia.Controls
}
else
{
- var dateValidationError = new DatePickerDateValidationErrorEventArgs(new ArgumentOutOfRangeException(nameof(text), "SelectedDate value is not valid."), text);
+ var dateValidationError = new CalendarDatePickerDateValidationErrorEventArgs(new ArgumentOutOfRangeException(nameof(text), "SelectedDate value is not valid."), text);
OnDateValidationError(dateValidationError);
if (dateValidationError.ThrowException)
@@ -970,7 +970,7 @@ namespace Avalonia.Controls
}
catch (FormatException ex)
{
- DatePickerDateValidationErrorEventArgs textParseError = new DatePickerDateValidationErrorEventArgs(ex, text);
+ CalendarDatePickerDateValidationErrorEventArgs textParseError = new CalendarDatePickerDateValidationErrorEventArgs(ex, text);
OnDateValidationError(textParseError);
if (textParseError.ThrowException)
@@ -986,11 +986,11 @@ namespace Avalonia.Controls
switch (SelectedDateFormat)
{
- case DatePickerFormat.Short:
+ case CalendarDatePickerFormat.Short:
return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.ShortDatePattern, dtfi));
- case DatePickerFormat.Long:
+ case CalendarDatePickerFormat.Long:
return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.LongDatePattern, dtfi));
- case DatePickerFormat.Custom:
+ case CalendarDatePickerFormat.Custom:
return string.Format(CultureInfo.CurrentCulture, d.ToString(CustomDateFormatString, dtfi));
}
return null;
@@ -1118,12 +1118,12 @@ namespace Avalonia.Controls
switch (SelectedDateFormat)
{
- case DatePickerFormat.Long:
+ case CalendarDatePickerFormat.Long:
{
watermarkText = string.Format(CultureInfo.CurrentCulture, watermarkFormat, dtfi.LongDatePattern.ToString());
break;
}
- case DatePickerFormat.Short:
+ case CalendarDatePickerFormat.Short:
default:
{
watermarkText = string.Format(CultureInfo.CurrentCulture, watermarkFormat, dtfi.ShortDatePattern.ToString());
@@ -1139,11 +1139,11 @@ namespace Avalonia.Controls
}
}
- private static bool IsValidSelectedDateFormat(DatePickerFormat value)
+ private static bool IsValidSelectedDateFormat(CalendarDatePickerFormat value)
{
- return value == DatePickerFormat.Long
- || value == DatePickerFormat.Short
- || value == DatePickerFormat.Custom;
+ return value == CalendarDatePickerFormat.Long
+ || value == CalendarDatePickerFormat.Short
+ || value == CalendarDatePickerFormat.Custom;
}
private static bool IsValidDateFormatString(string formatString)
{
diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs
index ece0ef97d9..0be7c4f67e 100644
--- a/src/Avalonia.Controls/Calendar/CalendarItem.cs
+++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs
@@ -909,7 +909,7 @@ namespace Avalonia.Controls.Primitives
case CalendarSelectionMode.SingleDate:
{
DateTime selectedDate = (DateTime)b.DataContext;
- Owner.DatePickerDisplayDateFlag = true;
+ Owner.CalendarDatePickerDisplayDateFlag = true;
if (Owner.SelectedDates.Count == 0)
{
Owner.SelectedDates.Add(selectedDate);
@@ -981,7 +981,7 @@ namespace Avalonia.Controls.Primitives
}
case CalendarSelectionMode.SingleDate:
{
- Owner.DatePickerDisplayDateFlag = true;
+ Owner.CalendarDatePickerDisplayDateFlag = true;
if (Owner.SelectedDates.Count == 0)
{
Owner.SelectedDates.Add(selectedDate);
diff --git a/src/Avalonia.Controls/Converters/MarginMultiplierConverter.cs b/src/Avalonia.Controls/Converters/MarginMultiplierConverter.cs
index 54bd6bcf39..9f3a6da9da 100644
--- a/src/Avalonia.Controls/Converters/MarginMultiplierConverter.cs
+++ b/src/Avalonia.Controls/Converters/MarginMultiplierConverter.cs
@@ -18,10 +18,24 @@ namespace Avalonia.Controls.Converters
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- if (!(value is int depth))
- return new Thickness(0);
-
- return new Thickness(Left ? Indent * depth : 0, Top ? Indent * depth : 0, Right ? Indent * depth : 0, Bottom ? Indent * depth : 0);
+ if (value is int scalarDepth)
+ {
+ return new Thickness(
+ Left ? Indent * scalarDepth : 0,
+ Top ? Indent * scalarDepth : 0,
+ Right ? Indent * scalarDepth : 0,
+ Bottom ? Indent * scalarDepth : 0);
+ }
+ else if (value is Thickness thinknessDepth)
+ {
+ return new Thickness(
+ Left ? Indent * thinknessDepth.Left : 0,
+ Top ? Indent * thinknessDepth.Top : 0,
+ Right ? Indent * thinknessDepth.Right : 0,
+ Bottom ? Indent * thinknessDepth.Bottom : 0);
+ }
+ return new Thickness(0);
+
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
diff --git a/src/Avalonia.Themes.Fluent/DatePicker.xaml b/src/Avalonia.Themes.Default/CalendarDatePicker.xaml
similarity index 97%
rename from src/Avalonia.Themes.Fluent/DatePicker.xaml
rename to src/Avalonia.Themes.Default/CalendarDatePicker.xaml
index 7adb1c2d5f..bc1aba1a03 100644
--- a/src/Avalonia.Themes.Fluent/DatePicker.xaml
+++ b/src/Avalonia.Themes.Default/CalendarDatePicker.xaml
@@ -8,7 +8,7 @@
-
-
diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml b/src/Avalonia.Themes.Default/DefaultTheme.xaml
index 67279fca99..83da5d3142 100644
--- a/src/Avalonia.Themes.Default/DefaultTheme.xaml
+++ b/src/Avalonia.Themes.Default/DefaultTheme.xaml
@@ -45,7 +45,7 @@
-
+
diff --git a/src/Avalonia.Themes.Default/Slider.xaml b/src/Avalonia.Themes.Default/Slider.xaml
index b21cbf3650..1d48a946fc 100644
--- a/src/Avalonia.Themes.Default/Slider.xaml
+++ b/src/Avalonia.Themes.Default/Slider.xaml
@@ -46,7 +46,7 @@
-
8,5,8,6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
diff --git a/src/Avalonia.Themes.Default/DatePicker.xaml b/src/Avalonia.Themes.Fluent/CalendarDatePicker.xaml
similarity index 97%
rename from src/Avalonia.Themes.Default/DatePicker.xaml
rename to src/Avalonia.Themes.Fluent/CalendarDatePicker.xaml
index 7adb1c2d5f..bc1aba1a03 100644
--- a/src/Avalonia.Themes.Default/DatePicker.xaml
+++ b/src/Avalonia.Themes.Fluent/CalendarDatePicker.xaml
@@ -8,7 +8,7 @@
-
-
diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.xaml b/src/Avalonia.Themes.Fluent/FluentTheme.xaml
index a20f075e21..36ae114f9b 100644
--- a/src/Avalonia.Themes.Fluent/FluentTheme.xaml
+++ b/src/Avalonia.Themes.Fluent/FluentTheme.xaml
@@ -23,6 +23,7 @@
+
@@ -44,7 +45,7 @@
-
+
diff --git a/src/Avalonia.Themes.Fluent/NumericUpDown.xaml b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
index 24cbb62908..08de50c6e3 100644
--- a/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
+++ b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
@@ -1,38 +1,60 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
diff --git a/src/Avalonia.Themes.Fluent/RepeatButton.xaml b/src/Avalonia.Themes.Fluent/RepeatButton.xaml
new file mode 100644
index 0000000000..12ba38d614
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/RepeatButton.xaml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+ 8,5,8,6
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Slider.xaml b/src/Avalonia.Themes.Fluent/Slider.xaml
index a57ea6cedd..539c448e0f 100644
--- a/src/Avalonia.Themes.Fluent/Slider.xaml
+++ b/src/Avalonia.Themes.Fluent/Slider.xaml
@@ -64,7 +64,7 @@
-
+
@@ -76,7 +76,7 @@
-
+
@@ -125,7 +125,7 @@
-
+
@@ -137,7 +137,7 @@
-
+
diff --git a/src/Avalonia.Themes.Fluent/TextBox.xaml b/src/Avalonia.Themes.Fluent/TextBox.xaml
index e89cf2b49c..49fc4b59b0 100644
--- a/src/Avalonia.Themes.Fluent/TextBox.xaml
+++ b/src/Avalonia.Themes.Fluent/TextBox.xaml
@@ -27,6 +27,7 @@
Grid.ColumnSpan="2"
TextBlock.FontWeight="Normal"
TextBlock.Foreground="{DynamicResource TextControlHeaderForeground}"
+ IsVisible="False"
Margin="{DynamicResource TextBoxTopHeaderMargin}" />
+
+
+
+
+
+
+
+
+
+
+
+
+ 8,5,8,6
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs b/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
index 6e175707e4..df871a67b4 100644
--- a/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
+++ b/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
@@ -322,7 +322,7 @@ namespace Avalonia.Base.UnitTests.Data.Core
{
"bar",
new BindingNotification(
- new MissingMemberException("Could not find CLR property 'Bar' on 'Avalonia.Base.UnitTests.Data.Core.ExpressionObserverTests_Property+WithoutBar'"),
+ new MissingMemberException("Could not find a matching property accessor for 'Bar' on 'Avalonia.Base.UnitTests.Data.Core.ExpressionObserverTests_Property+WithoutBar'"),
BindingErrorType.Error),
"baz",
},
diff --git a/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs b/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs
new file mode 100644
index 0000000000..0039f5670c
--- /dev/null
+++ b/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs
@@ -0,0 +1,47 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using JetBrains.Annotations;
+
+namespace Avalonia.Benchmarks.Data
+{
+ internal class AccessorTestObject : INotifyPropertyChanged
+ {
+ private string _test;
+
+ public string Test
+ {
+ get => _test;
+ set
+ {
+ if (_test == value)
+ {
+ return;
+ }
+
+ _test = value;
+
+ OnPropertyChanged();
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public void Execute()
+ {
+ }
+
+ public void Execute(object p0)
+ {
+ }
+
+ public void Execute(object p0, object p1)
+ {
+ }
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
diff --git a/tests/Avalonia.Benchmarks/Data/PropertyAccessorBenchmarks.cs b/tests/Avalonia.Benchmarks/Data/PropertyAccessorBenchmarks.cs
index 3d5a4029bb..6c5e0d3b53 100644
--- a/tests/Avalonia.Benchmarks/Data/PropertyAccessorBenchmarks.cs
+++ b/tests/Avalonia.Benchmarks/Data/PropertyAccessorBenchmarks.cs
@@ -1,9 +1,6 @@
using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
using Avalonia.Data.Core.Plugins;
using BenchmarkDotNet.Attributes;
-using JetBrains.Annotations;
namespace Avalonia.Benchmarks.Data
{
@@ -12,7 +9,7 @@ namespace Avalonia.Benchmarks.Data
{
private readonly InpcPropertyAccessorPlugin _inpcPlugin = new InpcPropertyAccessorPlugin();
private readonly MethodAccessorPlugin _methodPlugin = new MethodAccessorPlugin();
- private readonly TestObject _targetStrongRef = new TestObject();
+ private readonly AccessorTestObject _targetStrongRef = new AccessorTestObject();
private readonly WeakReference