Browse Source

Converted several "dataValidation" properties to StyledProperty

Changed Button.IsPressed to a read-only DirectProperty
pull/10370/head
Tom Edwards 3 years ago
parent
commit
f36cf7e3ba
  1. 45
      src/Avalonia.Controls/Button.cs
  2. 10
      src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.Properties.cs
  3. 1
      src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs
  4. 22
      src/Avalonia.Controls/MenuItem.cs
  5. 31
      src/Avalonia.Controls/NativeMenuItem.cs
  6. 36
      src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs
  7. 12
      src/Avalonia.Controls/SplitButton/SplitButton.cs
  8. 14
      src/Avalonia.Controls/TrayIcon.cs
  9. 12
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

45
src/Avalonia.Controls/Button.cs

@ -1,11 +1,9 @@
using System; using System;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows.Input; using System.Windows.Input;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata; using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -48,9 +46,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Command"/> property. /// Defines the <see cref="Command"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<Button, ICommand?> CommandProperty = public static readonly StyledProperty<ICommand?> CommandProperty =
AvaloniaProperty.RegisterDirect<Button, ICommand?>(nameof(Command), AvaloniaProperty.Register<Button, ICommand?>(nameof(Command), enableDataValidation: true);
button => button.Command, (button, command) => button.Command = command, enableDataValidation: true);
/// <summary> /// <summary>
/// Defines the <see cref="HotKey"/> property. /// Defines the <see cref="HotKey"/> property.
@ -85,8 +82,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="IsPressed"/> property. /// Defines the <see cref="IsPressed"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<bool> IsPressedProperty = public static readonly DirectProperty<Button, bool> IsPressedProperty =
AvaloniaProperty.Register<Button, bool>(nameof(IsPressed)); AvaloniaProperty.RegisterDirect<Button, bool>(nameof(IsPressed), b => b.IsPressed);
/// <summary> /// <summary>
/// Defines the <see cref="Flyout"/> property /// Defines the <see cref="Flyout"/> property
@ -94,10 +91,10 @@ namespace Avalonia.Controls
public static readonly StyledProperty<FlyoutBase?> FlyoutProperty = public static readonly StyledProperty<FlyoutBase?> FlyoutProperty =
AvaloniaProperty.Register<Button, FlyoutBase?>(nameof(Flyout)); AvaloniaProperty.Register<Button, FlyoutBase?>(nameof(Flyout));
private ICommand? _command;
private bool _commandCanExecute = true; private bool _commandCanExecute = true;
private KeyGesture? _hotkey; private KeyGesture? _hotkey;
private bool _isFlyoutOpen = false; private bool _isFlyoutOpen = false;
private bool _isPressed = false;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="Button"/> class. /// Initializes static members of the <see cref="Button"/> class.
@ -138,8 +135,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public ICommand? Command public ICommand? Command
{ {
get => _command; get => GetValue(CommandProperty);
set => SetAndRaise(CommandProperty, ref _command, value); set => SetValue(CommandProperty, value);
} }
/// <summary> /// <summary>
@ -185,8 +182,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public bool IsPressed public bool IsPressed
{ {
get => GetValue(IsPressedProperty); get => _isPressed;
private set => SetValue(IsPressedProperty, value); private set => SetAndRaise(IsPressedProperty, ref _isPressed, value);
} }
/// <summary> /// <summary>
@ -248,7 +245,7 @@ namespace Avalonia.Controls
{ {
if (_hotkey != null) // Control attached again, set Hotkey to create a hotkey manager for this control if (_hotkey != null) // Control attached again, set Hotkey to create a hotkey manager for this control
{ {
HotKey = _hotkey; SetCurrentValue(HotKeyProperty, _hotkey);
} }
base.OnAttachedToLogicalTree(e); base.OnAttachedToLogicalTree(e);
@ -267,7 +264,7 @@ namespace Avalonia.Controls
if (HotKey != null) if (HotKey != null)
{ {
_hotkey = HotKey; _hotkey = HotKey;
HotKey = null; SetCurrentValue(HotKeyProperty, null);
} }
base.OnDetachedFromLogicalTree(e); base.OnDetachedFromLogicalTree(e);
@ -291,17 +288,17 @@ namespace Avalonia.Controls
break; break;
case Key.Space: case Key.Space:
{
if (ClickMode == ClickMode.Press)
{ {
OnClick(); if (ClickMode == ClickMode.Press)
{
OnClick();
}
IsPressed = true;
e.Handled = true;
break;
} }
IsPressed = true;
e.Handled = true;
break;
}
case Key.Escape when Flyout != null: case Key.Escape when Flyout != null:
// If Flyout doesn't have focusable content, close the flyout here // If Flyout doesn't have focusable content, close the flyout here
CloseFlyout(); CloseFlyout();
@ -592,7 +589,7 @@ namespace Avalonia.Controls
{ {
flyout.Opened -= Flyout_Opened; flyout.Opened -= Flyout_Opened;
flyout.Closed -= Flyout_Closed; flyout.Closed -= Flyout_Closed;
} }
} }
/// <summary> /// <summary>
@ -671,7 +668,7 @@ namespace Avalonia.Controls
void ICommandSource.CanExecuteChanged(object sender, EventArgs e) => this.CanExecuteChanged(sender, e); void ICommandSource.CanExecuteChanged(object sender, EventArgs e) => this.CanExecuteChanged(sender, e);
void IClickableControl.RaiseClick() => OnClick(); void IClickableControl.RaiseClick() => OnClick();
/// <summary> /// <summary>
/// Event handler for when the button's flyout is opened. /// Event handler for when the button's flyout is opened.
/// </summary> /// </summary>

10
src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.Properties.cs

@ -50,11 +50,9 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="SelectedDate"/> property. /// Defines the <see cref="SelectedDate"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<CalendarDatePicker, DateTime?> SelectedDateProperty = public static readonly StyledProperty<DateTime?> SelectedDateProperty =
AvaloniaProperty.RegisterDirect<CalendarDatePicker, DateTime?>( AvaloniaProperty.Register<CalendarDatePicker, DateTime?>(
nameof(SelectedDate), nameof(SelectedDate),
o => o.SelectedDate,
(o, v) => o.SelectedDate = v,
enableDataValidation: true, enableDataValidation: true,
defaultBindingMode:BindingMode.TwoWay); defaultBindingMode:BindingMode.TwoWay);
@ -211,8 +209,8 @@ namespace Avalonia.Controls
/// </exception> /// </exception>
public DateTime? SelectedDate public DateTime? SelectedDate
{ {
get => _selectedDate; get => GetValue(SelectedDateProperty);
set => SetAndRaise(SelectedDateProperty, ref _selectedDate, value); set => SetValue(SelectedDateProperty, value);
} }
/// <summary> /// <summary>

1
src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs

@ -45,7 +45,6 @@ namespace Avalonia.Controls
private DateTime? _onOpenSelectedDate; private DateTime? _onOpenSelectedDate;
private bool _settingSelectedDate; private bool _settingSelectedDate;
private DateTime? _selectedDate;
private bool _suspendTextChangeHandler; private bool _suspendTextChangeHandler;
private bool _isPopupClosing; private bool _isPopupClosing;
private bool _ignoreButtonClick; private bool _ignoreButtonClick;

22
src/Avalonia.Controls/MenuItem.cs

@ -27,11 +27,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Command"/> property. /// Defines the <see cref="Command"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<MenuItem, ICommand?> CommandProperty = public static readonly StyledProperty<ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<MenuItem>( Button.CommandProperty.AddOwner<MenuItem>(new(enableDataValidation: true));
menuItem => menuItem.Command,
(menuItem, command) => menuItem.Command = command,
enableDataValidation: true);
/// <summary> /// <summary>
/// Defines the <see cref="HotKey"/> property. /// Defines the <see cref="HotKey"/> property.
@ -113,7 +110,6 @@ namespace Avalonia.Controls
private static readonly ITemplate<Panel> DefaultPanel = private static readonly ITemplate<Panel> DefaultPanel =
new FuncTemplate<Panel>(() => new StackPanel()); new FuncTemplate<Panel>(() => new StackPanel());
private ICommand? _command;
private bool _commandCanExecute = true; private bool _commandCanExecute = true;
private bool _commandBindingError; private bool _commandBindingError;
private Popup? _popup; private Popup? _popup;
@ -217,8 +213,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public ICommand? Command public ICommand? Command
{ {
get { return _command; } get => GetValue(CommandProperty);
set { SetAndRaise(CommandProperty, ref _command, value); } set => SetValue(CommandProperty, value);
} }
/// <summary> /// <summary>
@ -337,7 +333,7 @@ namespace Avalonia.Controls
/// <remarks> /// <remarks>
/// This has the same effect as setting <see cref="IsSubMenuOpen"/> to true. /// This has the same effect as setting <see cref="IsSubMenuOpen"/> to true.
/// </remarks> /// </remarks>
public void Open() => IsSubMenuOpen = true; public void Open() => SetCurrentValue(IsSubMenuOpenProperty, true);
/// <summary> /// <summary>
/// Closes the submenu. /// Closes the submenu.
@ -345,7 +341,7 @@ namespace Avalonia.Controls
/// <remarks> /// <remarks>
/// This has the same effect as setting <see cref="IsSubMenuOpen"/> to false. /// This has the same effect as setting <see cref="IsSubMenuOpen"/> to false.
/// </remarks> /// </remarks>
public void Close() => IsSubMenuOpen = false; public void Close() => SetCurrentValue(IsSubMenuOpenProperty, false);
/// <inheritdoc/> /// <inheritdoc/>
void IMenuItem.RaiseClick() => RaiseEvent(new RoutedEventArgs(ClickEvent)); void IMenuItem.RaiseClick() => RaiseEvent(new RoutedEventArgs(ClickEvent));
@ -369,7 +365,7 @@ namespace Avalonia.Controls
{ {
if (_hotkey != null) // Control attached again, set Hotkey to create a hotkey manager for this control if (_hotkey != null) // Control attached again, set Hotkey to create a hotkey manager for this control
{ {
HotKey = _hotkey; SetCurrentValue(HotKeyProperty, _hotkey);
} }
base.OnAttachedToLogicalTree(e); base.OnAttachedToLogicalTree(e);
@ -397,7 +393,7 @@ namespace Avalonia.Controls
if (HotKey != null) if (HotKey != null)
{ {
_hotkey = HotKey; _hotkey = HotKey;
HotKey = null; SetCurrentValue(HotKeyProperty, null);
} }
base.OnDetachedFromLogicalTree(e); base.OnDetachedFromLogicalTree(e);
@ -663,7 +659,7 @@ namespace Avalonia.Controls
} }
RaiseEvent(new RoutedEventArgs(SubmenuOpenedEvent)); RaiseEvent(new RoutedEventArgs(SubmenuOpenedEvent));
IsSelected = true; SetCurrentValue(IsSelectedProperty, true);
PseudoClasses.Add(":open"); PseudoClasses.Add(":open");
} }
else else

31
src/Avalonia.Controls/NativeMenuItem.cs

@ -9,7 +9,6 @@ namespace Avalonia.Controls
{ {
public class NativeMenuItem : NativeMenuItemBase, INativeMenuItemExporterEventsImplBridge public class NativeMenuItem : NativeMenuItemBase, INativeMenuItemExporterEventsImplBridge
{ {
private ICommand? _command;
private readonly CanExecuteChangedSubscriber _canExecuteChangedSubscriber; private readonly CanExecuteChangedSubscriber _canExecuteChangedSubscriber;
class CanExecuteChangedSubscriber : IWeakEventSubscriber<EventArgs> class CanExecuteChangedSubscriber : IWeakEventSubscriber<EventArgs>
@ -100,11 +99,8 @@ namespace Avalonia.Controls
set => SetValue(ToggleTypeProperty, value); set => SetValue(ToggleTypeProperty, value);
} }
public static readonly DirectProperty<NativeMenuItem, ICommand?> CommandProperty = public static readonly StyledProperty<ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<NativeMenuItem>( Button.CommandProperty.AddOwner<NativeMenuItem>(new(enableDataValidation: true));
menuItem => menuItem.Command,
(menuItem, command) => menuItem.Command = command,
enableDataValidation: true);
/// <summary> /// <summary>
/// Defines the <see cref="CommandParameter"/> property. /// Defines the <see cref="CommandParameter"/> property.
@ -130,19 +126,8 @@ namespace Avalonia.Controls
public ICommand? Command public ICommand? Command
{ {
get => _command; get => GetValue(CommandProperty);
set set => SetValue(CommandProperty, value);
{
if (_command != null)
WeakEvents.CommandCanExecuteChanged.Unsubscribe(_command, _canExecuteChangedSubscriber);
SetAndRaise(CommandProperty, ref _command, value);
if (_command != null)
WeakEvents.CommandCanExecuteChanged.Subscribe(_command, _canExecuteChangedSubscriber);
CanExecuteChanged();
}
} }
/// <summary> /// <summary>
@ -180,6 +165,14 @@ namespace Avalonia.Controls
throw new InvalidOperationException("NativeMenu already has a parent"); throw new InvalidOperationException("NativeMenu already has a parent");
newMenu.Parent = this; newMenu.Parent = this;
} }
else if (change.Property == CommandProperty)
{
if (change.OldValue is ICommand oldCommand)
WeakEvents.CommandCanExecuteChanged.Unsubscribe(oldCommand, _canExecuteChangedSubscriber);
if (change.NewValue is ICommand newCommand)
WeakEvents.CommandCanExecuteChanged.Subscribe(newCommand, _canExecuteChangedSubscriber);
CanExecuteChanged();
}
} }
} }

36
src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs

@ -91,8 +91,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Text"/> property. /// Defines the <see cref="Text"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<NumericUpDown, string?> TextProperty = public static readonly StyledProperty<string?> TextProperty =
AvaloniaProperty.RegisterDirect<NumericUpDown, string?>(nameof(Text), o => o.Text, (o, v) => o.Text = v, AvaloniaProperty.Register<NumericUpDown, string?>(nameof(Text),
defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true); defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true);
/// <summary> /// <summary>
@ -104,9 +104,9 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Value"/> property. /// Defines the <see cref="Value"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<NumericUpDown, decimal?> ValueProperty = public static readonly StyledProperty<decimal?> ValueProperty =
AvaloniaProperty.RegisterDirect<NumericUpDown, decimal?>(nameof(Value), updown => updown.Value, AvaloniaProperty.Register<NumericUpDown, decimal?>(nameof(Value), coerce: (s,v) => ((NumericUpDown)s).OnCoerceValue(v),
(updown, v) => updown.Value = v, defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true); defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true);
/// <summary> /// <summary>
/// Defines the <see cref="Watermark"/> property. /// Defines the <see cref="Watermark"/> property.
@ -128,8 +128,6 @@ namespace Avalonia.Controls
private IDisposable? _textBoxTextChangedSubscription; private IDisposable? _textBoxTextChangedSubscription;
private decimal? _value;
private string? _text;
private bool _internalValueSet; private bool _internalValueSet;
private bool _isSyncingTextAndValueProperties; private bool _isSyncingTextAndValueProperties;
private bool _isTextChangedFromUI; private bool _isTextChangedFromUI;
@ -250,8 +248,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public string? Text public string? Text
{ {
get { return _text; } get => GetValue(TextProperty);
set { SetAndRaise(TextProperty, ref _text, value); } set => SetValue(TextProperty, value);
} }
/// <summary> /// <summary>
@ -270,12 +268,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public decimal? Value public decimal? Value
{ {
get { return _value; } get => GetValue(ValueProperty);
set set => SetValue(ValueProperty, value);
{
value = OnCoerceValue(value);
SetAndRaise(ValueProperty, ref _value, value);
}
} }
/// <summary> /// <summary>
@ -500,7 +494,7 @@ namespace Avalonia.Controls
SyncTextAndValueProperties(true, Text); SyncTextAndValueProperties(true, Text);
} }
} }
/// <summary> /// <summary>
/// Called when the <see cref="Text"/> property value changed. /// Called when the <see cref="Text"/> property value changed.
/// </summary> /// </summary>
@ -667,7 +661,7 @@ namespace Avalonia.Controls
{ {
result = Minimum; result = Minimum;
} }
SetCurrentValue(ValueProperty, MathUtilities.Clamp(result, Minimum, Maximum)); SetCurrentValue(ValueProperty, MathUtilities.Clamp(result, Minimum, Maximum));
} }
@ -677,7 +671,7 @@ namespace Avalonia.Controls
private void OnDecrement() private void OnDecrement()
{ {
decimal result; decimal result;
if (Value.HasValue) if (Value.HasValue)
{ {
result = Value.Value - Increment; result = Value.Value - Increment;
@ -686,7 +680,7 @@ namespace Avalonia.Controls
{ {
result = Maximum; result = Maximum;
} }
SetCurrentValue(ValueProperty, MathUtilities.Clamp(result, Minimum, Maximum)); SetCurrentValue(ValueProperty, MathUtilities.Clamp(result, Minimum, Maximum));
} }
@ -704,7 +698,7 @@ namespace Avalonia.Controls
{ {
validDirections = ValidSpinDirections.Increase | ValidSpinDirections.Decrease; validDirections = ValidSpinDirections.Increase | ValidSpinDirections.Decrease;
} }
if (Value < Maximum) if (Value < Maximum)
{ {
validDirections = validDirections | ValidSpinDirections.Increase; validDirections = validDirections | ValidSpinDirections.Increase;
@ -1058,7 +1052,7 @@ namespace Avalonia.Controls
{ {
return null; return null;
} }
if (TextConverter != null) if (TextConverter != null)
{ {
var valueFromText = TextConverter.Convert(text, typeof(decimal?), null, CultureInfo.CurrentCulture); var valueFromText = TextConverter.Convert(text, typeof(decimal?), null, CultureInfo.CurrentCulture);

12
src/Avalonia.Controls/SplitButton/SplitButton.cs

@ -42,10 +42,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Command"/> property. /// Defines the <see cref="Command"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<SplitButton, ICommand?> CommandProperty = public static readonly StyledProperty<ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<SplitButton>( Button.CommandProperty.AddOwner<SplitButton>();
splitButton => splitButton.Command,
(splitButton, command) => splitButton.Command = command);
/// <summary> /// <summary>
/// Defines the <see cref="CommandParameter"/> property. /// Defines the <see cref="CommandParameter"/> property.
@ -59,8 +57,6 @@ namespace Avalonia.Controls
public static readonly StyledProperty<FlyoutBase?> FlyoutProperty = public static readonly StyledProperty<FlyoutBase?> FlyoutProperty =
Button.FlyoutProperty.AddOwner<SplitButton>(); Button.FlyoutProperty.AddOwner<SplitButton>();
private ICommand? _Command;
private Button? _primaryButton = null; private Button? _primaryButton = null;
private Button? _secondaryButton = null; private Button? _secondaryButton = null;
@ -83,8 +79,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public ICommand? Command public ICommand? Command
{ {
get => _Command; get => GetValue(CommandProperty);
set => SetAndRaise(CommandProperty, ref _Command, value); set => SetValue(CommandProperty, value);
} }
/// <summary> /// <summary>

14
src/Avalonia.Controls/TrayIcon.cs

@ -13,13 +13,10 @@ namespace Avalonia.Controls
public sealed class TrayIcons : AvaloniaList<TrayIcon> public sealed class TrayIcons : AvaloniaList<TrayIcon>
{ {
} }
public class TrayIcon : AvaloniaObject, INativeMenuExporterProvider, IDisposable public class TrayIcon : AvaloniaObject, INativeMenuExporterProvider, IDisposable
{ {
private readonly ITrayIconImpl? _impl; private readonly ITrayIconImpl? _impl;
private ICommand? _command;
private TrayIcon(ITrayIconImpl? impl) private TrayIcon(ITrayIconImpl? impl)
{ {
@ -85,11 +82,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Command"/> property. /// Defines the <see cref="Command"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<TrayIcon, ICommand?> CommandProperty = public static readonly StyledProperty<ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<TrayIcon>( Button.CommandProperty.AddOwner<TrayIcon>(new(enableDataValidation: true));
trayIcon => trayIcon.Command,
(trayIcon, command) => trayIcon.Command = command,
enableDataValidation: true);
/// <summary> /// <summary>
/// Defines the <see cref="CommandParameter"/> property. /// Defines the <see cref="CommandParameter"/> property.
@ -136,8 +130,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public ICommand? Command public ICommand? Command
{ {
get => _command; get => GetValue(CommandProperty);
set => SetAndRaise(CommandProperty, ref _command, value); set => SetValue(CommandProperty, value);
} }
/// <summary> /// <summary>

12
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

@ -21,17 +21,6 @@ namespace Avalonia.Markup.Xaml.UnitTests
{ {
public class XamlIlTests : XamlTestBase public class XamlIlTests : XamlTestBase
{ {
[Fact]
public void Binding_Button_IsPressed_ShouldWork()
{
var parsed = (Button)AvaloniaRuntimeXamlLoader.Parse(@"
<Button xmlns='https://github.com/avaloniaui' IsPressed='{Binding IsPressed, Mode=TwoWay}' />");
var ctx = new XamlIlBugTestsDataContext();
parsed.DataContext = ctx;
parsed.SetValue(Button.IsPressedProperty, true);
Assert.True(ctx.IsPressed);
}
[Fact] [Fact]
public void Transitions_Should_Be_Properly_Parsed() public void Transitions_Should_Be_Properly_Parsed()
{ {
@ -426,7 +415,6 @@ namespace Avalonia.Markup.Xaml.UnitTests
public class XamlIlBugTestsDataContext : INotifyPropertyChanged public class XamlIlBugTestsDataContext : INotifyPropertyChanged
{ {
public bool IsPressed { get; set; }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)

Loading…
Cancel
Save