Skip to content
1 change: 0 additions & 1 deletion src/Avalonia.Base/AvaloniaObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public class AvaloniaObject : IAvaloniaObject, IAvaloniaObjectDebug, INotifyProp
public AvaloniaObject()
{
VerifyAccess();
AvaloniaPropertyRegistry.Instance.NotifyInitialized(this);
}

/// <summary>
Expand Down
39 changes: 0 additions & 39 deletions src/Avalonia.Base/AvaloniaProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public abstract class AvaloniaProperty : IEquatable<AvaloniaProperty>
public static readonly object UnsetValue = new UnsetValueType();

private static int s_nextId;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _initialized;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _changed;
private readonly PropertyMetadata _defaultMetadata;
private readonly Dictionary<Type, PropertyMetadata> _metadata;
Expand Down Expand Up @@ -53,7 +52,6 @@ protected AvaloniaProperty(
throw new ArgumentException("'name' may not contain periods.");
}

_initialized = new Subject<AvaloniaPropertyChangedEventArgs>();
_changed = new Subject<AvaloniaPropertyChangedEventArgs>();
_metadata = new Dictionary<Type, PropertyMetadata>();

Expand Down Expand Up @@ -81,7 +79,6 @@ protected AvaloniaProperty(
Contract.Requires<ArgumentNullException>(source != null);
Contract.Requires<ArgumentNullException>(ownerType != null);

_initialized = source._initialized;
_changed = source._changed;
_metadata = new Dictionary<Type, PropertyMetadata>();

Expand Down Expand Up @@ -136,22 +133,6 @@ protected AvaloniaProperty(
/// </summary>
public virtual bool IsReadOnly => false;

/// <summary>
/// Gets an observable that is fired when this property is initialized on a
/// new <see cref="AvaloniaObject"/> instance.
/// </summary>
/// <remarks>
/// This observable is fired each time a new <see cref="AvaloniaObject"/> is constructed
/// for all properties registered on the object's type. The default value of the property
/// for the object is passed in the args' NewValue (OldValue will always be
/// <see cref="UnsetValue"/>.
/// </remarks>
/// <value>
/// An observable that is fired when this property is initialized on a new
/// <see cref="AvaloniaObject"/> instance.
/// </value>
public IObservable<AvaloniaPropertyChangedEventArgs> Initialized => _initialized;

/// <summary>
/// Gets an observable that is fired when this property changes on any
/// <see cref="AvaloniaObject"/> instance.
Expand Down Expand Up @@ -488,26 +469,6 @@ public override string ToString()
return Name;
}

/// <summary>
/// True if <see cref="Initialized"/> has any observers.
/// </summary>
internal bool HasNotifyInitializedObservers => _initialized.HasObservers;

/// <summary>
/// Notifies the <see cref="Initialized"/> observable.
/// </summary>
/// <param name="o">The object being initialized.</param>
internal abstract void NotifyInitialized(IAvaloniaObject o);

/// <summary>
/// Notifies the <see cref="Initialized"/> observable.
/// </summary>
/// <param name="e">The observable arguments.</param>
internal void NotifyInitialized(AvaloniaPropertyChangedEventArgs e)
{
_initialized.OnNext(e);
}

/// <summary>
/// Notifies the <see cref="Changed"/> observable.
/// </summary>
Expand Down
45 changes: 0 additions & 45 deletions src/Avalonia.Base/AvaloniaPropertyRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,51 +415,6 @@ public void RegisterAttached(Type type, AvaloniaProperty property)
_inheritedCache.Clear();
}

internal void NotifyInitialized(AvaloniaObject o)
{
Contract.Requires<ArgumentNullException>(o != null);

var type = o.GetType();

if (!_initializedCache.TryGetValue(type, out var initializationData))
{
var visited = new HashSet<AvaloniaProperty>();

initializationData = new List<PropertyInitializationData>();

foreach (AvaloniaProperty property in GetRegistered(type))
{
if (property.IsDirect)
{
initializationData.Add(new PropertyInitializationData(property, (IDirectPropertyAccessor)property));
}
else
{
initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));
}

visited.Add(property);
}

foreach (AvaloniaProperty property in GetRegisteredAttached(type))
{
if (!visited.Contains(property))
{
initializationData.Add(new PropertyInitializationData(property, (IStyledPropertyAccessor)property, type));

visited.Add(property);
}
}

_initializedCache.Add(type, initializationData);
}

foreach (PropertyInitializationData data in initializationData)
{
data.Property.NotifyInitialized(o);
}
}

private readonly struct PropertyInitializationData
{
public AvaloniaProperty Property { get; }
Expand Down
15 changes: 0 additions & 15 deletions src/Avalonia.Base/DirectPropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,6 @@ public TValue GetUnsetValue(Type type)
return (DirectPropertyMetadata<TValue>)base.GetMetadata(type);
}

/// <inheritdoc/>
internal override void NotifyInitialized(IAvaloniaObject o)
{
if (HasNotifyInitializedObservers)
{
var e = new AvaloniaPropertyChangedEventArgs<TValue>(
o,
this,
default,
InvokeGetter(o),
BindingPriority.Unset);
NotifyInitialized(e);
}
}

/// <inheritdoc/>
internal override void RouteClearValue(IAvaloniaObject o)
{
Expand Down
15 changes: 0 additions & 15 deletions src/Avalonia.Base/StyledPropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,6 @@ public override string ToString()
/// <inheritdoc/>
object IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultBoxedValue(type);

/// <inheritdoc/>
internal override void NotifyInitialized(IAvaloniaObject o)
{
if (HasNotifyInitializedObservers)
{
var e = new AvaloniaPropertyChangedEventArgs<TValue>(
o,
this,
default,
o.GetValue(this),
BindingPriority.Unset);
NotifyInitialized(e);
}
}

/// <inheritdoc/>
internal override void RouteClearValue(IAvaloniaObject o)
{
Expand Down
8 changes: 5 additions & 3 deletions src/Avalonia.Controls.DataGrid/DataGrid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@ private void OnAreRowGroupHeadersFrozenChanged(AvaloniaPropertyChangedEventArgs
public bool IsValid
{
get { return _isValid; }
internal set { SetAndRaise(IsValidProperty, ref _isValid, value); }
internal set
{
SetAndRaise(IsValidProperty, ref _isValid, value);
PseudoClasses.Set(":invalid", !value);
}
}

public static readonly StyledProperty<double> MaxColumnWidthProperty =
Expand Down Expand Up @@ -656,8 +660,6 @@ static DataGrid()
HorizontalScrollBarVisibilityProperty,
VerticalScrollBarVisibilityProperty);

PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid");

ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
Expand Down
25 changes: 24 additions & 1 deletion src/Avalonia.Controls/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ static Button()
CommandProperty.Changed.Subscribe(CommandChanged);
IsDefaultProperty.Changed.Subscribe(IsDefaultChanged);
IsCancelProperty.Changed.Subscribe(IsCancelChanged);
PseudoClass<Button>(IsPressedProperty, ":pressed");
}

public Button()
{
UpdatePseudoClasses(IsPressed);
}

/// <summary>
Expand Down Expand Up @@ -312,6 +316,20 @@ protected override void OnPointerCaptureLost(PointerCaptureLostEventArgs e)
IsPressed = false;
}

protected override void OnPropertyChanged<T>(
AvaloniaProperty<T> property,
Optional<T> oldValue,
BindingValue<T> newValue,
BindingPriority priority)
{
base.OnPropertyChanged(property, oldValue, newValue, priority);

if (property == IsPressedProperty)
{
UpdatePseudoClasses(newValue.GetValueOrDefault<bool>());
}
}

protected override void UpdateDataValidation<T>(AvaloniaProperty<T> property, BindingValue<T> value)
{
base.UpdateDataValidation(property, value);
Expand Down Expand Up @@ -474,5 +492,10 @@ private void RootCancelKeyDown(object sender, KeyEventArgs e)
OnClick();
}
}

private void UpdatePseudoClasses(bool isPressed)
{
PseudoClasses.Set(":pressed", isPressed);
}
}
}
28 changes: 26 additions & 2 deletions src/Avalonia.Controls/ButtonSpinner.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;

Expand Down Expand Up @@ -34,6 +35,11 @@ public class ButtonSpinner : Spinner
public static readonly StyledProperty<Location> ButtonSpinnerLocationProperty =
AvaloniaProperty.Register<ButtonSpinner, Location>(nameof(ButtonSpinnerLocation), Location.Right);

public ButtonSpinner()
{
UpdatePseudoClasses(ButtonSpinnerLocation);
}

private Button _decreaseButton;
/// <summary>
/// Gets or sets the DecreaseButton template part.
Expand Down Expand Up @@ -85,8 +91,6 @@ private Button IncreaseButton
static ButtonSpinner()
{
AllowSpinProperty.Changed.Subscribe(AllowSpinChanged);
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Left, ":left");
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Right, ":right");
}

/// <summary>
Expand Down Expand Up @@ -201,6 +205,20 @@ protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
}
}

protected override void OnPropertyChanged<T>(
AvaloniaProperty<T> property,
Optional<T> oldValue,
BindingValue<T> newValue,
BindingPriority priority)
{
base.OnPropertyChanged(property, oldValue, newValue, priority);

if (property == ButtonSpinnerLocationProperty)
{
UpdatePseudoClasses(newValue.GetValueOrDefault<Location>());
}
}

protected override void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue)
{
SetButtonUsage();
Expand Down Expand Up @@ -259,5 +277,11 @@ private void OnButtonClick(object sender, RoutedEventArgs e)
OnSpin(new SpinEventArgs(SpinEvent, direction));
}
}

private void UpdatePseudoClasses(Location location)
{
PseudoClasses.Set(":left", location == Location.Left);
PseudoClasses.Set(":right", location == Location.Right);
}
}
}
20 changes: 0 additions & 20 deletions src/Avalonia.Controls/ControlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,6 @@ public static T FindControl<T>(this IControl control, string name) where T : cla
return nameScope.Find<T>(name);
}

/// <summary>
/// Adds or removes a pseudoclass depending on a boolean value.
/// </summary>
/// <param name="classes">The pseudoclasses collection.</param>
/// <param name="name">The name of the pseudoclass to set.</param>
/// <param name="value">True to add the pseudoclass or false to remove.</param>
public static void Set(this IPseudoClasses classes, string name, bool value)
{
Contract.Requires<ArgumentNullException>(classes != null);

if (value)
{
classes.Add(name);
}
else
{
classes.Remove(name);
}
}

/// <summary>
/// Sets a pseudoclass depending on an observable trigger.
/// </summary>
Expand Down
Loading