Browse Source

Merge pull request #1869 from AvaloniaUI/fixes/1866-affects-not-global

Make Affects/Pseudoclass methods non-global by default
pull/1886/head
Steven Kirk 8 years ago
committed by GitHub
parent
commit
22958bccc6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/Avalonia.Controls/Border.cs
  2. 2
      src/Avalonia.Controls/Button.cs
  3. 6
      src/Avalonia.Controls/ButtonSpinner.cs
  4. 4
      src/Avalonia.Controls/ContentControl.cs
  5. 2
      src/Avalonia.Controls/Decorator.cs
  6. 6
      src/Avalonia.Controls/DrawingPresenter.cs
  7. 10
      src/Avalonia.Controls/Expander.cs
  8. 3
      src/Avalonia.Controls/Image.cs
  9. 4
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  10. 2
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  11. 2
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  12. 2
      src/Avalonia.Controls/Primitives/AccessText.cs
  13. 4
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  14. 6
      src/Avalonia.Controls/Primitives/ToggleButton.cs
  15. 4
      src/Avalonia.Controls/Primitives/Track.cs
  16. 6
      src/Avalonia.Controls/ProgressBar.cs
  17. 5
      src/Avalonia.Controls/Shapes/Shape.cs
  18. 2
      src/Avalonia.Controls/Slider.cs
  19. 4
      src/Avalonia.Controls/StackPanel.cs
  20. 2
      src/Avalonia.Controls/TabControl.cs
  21. 9
      src/Avalonia.Controls/TextBlock.cs
  22. 2
      src/Avalonia.Controls/TopLevel.cs
  23. 2
      src/Avalonia.Controls/WrapPanel.cs
  24. 6
      src/Avalonia.Input/InputElement.cs
  25. 68
      src/Avalonia.Layout/Layoutable.cs
  26. 45
      src/Avalonia.Styling/StyledElement.cs
  27. 36
      src/Avalonia.Visuals/Visual.cs

4
src/Avalonia.Controls/Border.cs

@ -43,8 +43,8 @@ namespace Avalonia.Controls
/// </summary>
static Border()
{
AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure(BorderThicknessProperty);
AffectsRender<Border>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure<Border>(BorderThicknessProperty);
}
/// <summary>

2
src/Avalonia.Controls/Button.cs

@ -80,7 +80,7 @@ namespace Avalonia.Controls
FocusableProperty.OverrideDefaultValue(typeof(Button), true);
CommandProperty.Changed.Subscribe(CommandChanged);
IsDefaultProperty.Changed.Subscribe(IsDefaultChanged);
PseudoClass(IsPressedProperty, ":pressed");
PseudoClass<Button>(IsPressedProperty, ":pressed");
}
/// <summary>

6
src/Avalonia.Controls/ButtonSpinner.cs

@ -85,8 +85,8 @@ namespace Avalonia.Controls
static ButtonSpinner()
{
AllowSpinProperty.Changed.Subscribe(AllowSpinChanged);
PseudoClass(ButtonSpinnerLocationProperty, location => location == Location.Left, ":left");
PseudoClass(ButtonSpinnerLocationProperty, location => location == Location.Right, ":right");
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Left, ":left");
PseudoClass<ButtonSpinner, Location>(ButtonSpinnerLocationProperty, location => location == Location.Right, ":right");
}
/// <summary>
@ -260,4 +260,4 @@ namespace Avalonia.Controls
}
}
}
}
}

4
src/Avalonia.Controls/ContentControl.cs

@ -45,8 +45,8 @@ namespace Avalonia.Controls
static ContentControl()
{
ContentControlMixin.Attach<ContentControl>(ContentProperty, x => x.LogicalChildren);
PseudoClass(ContentProperty, x => x != null, ":valid");
PseudoClass(ContentProperty, x => x == null, ":invalid");
PseudoClass<ContentControl, object>(ContentProperty, x => x != null, ":valid");
PseudoClass<ContentControl, object>(ContentProperty, x => x == null, ":invalid");
}
/// <summary>

2
src/Avalonia.Controls/Decorator.cs

@ -28,7 +28,7 @@ namespace Avalonia.Controls
/// </summary>
static Decorator()
{
AffectsMeasure(ChildProperty, PaddingProperty);
AffectsMeasure<Decorator>(ChildProperty, PaddingProperty);
ChildProperty.Changed.AddClassHandler<Decorator>(x => x.ChildChanged);
}

6
src/Avalonia.Controls/DrawingPresenter.cs

@ -8,8 +8,8 @@ namespace Avalonia.Controls
{
static DrawingPresenter()
{
AffectsMeasure(DrawingProperty);
AffectsRender(DrawingProperty);
AffectsMeasure<DrawingPresenter>(DrawingProperty);
AffectsRender<DrawingPresenter>(DrawingProperty);
}
public static readonly StyledProperty<Drawing> DrawingProperty =
@ -56,4 +56,4 @@ namespace Avalonia.Controls
}
}
}
}
}

10
src/Avalonia.Controls/Expander.cs

@ -35,12 +35,12 @@ namespace Avalonia.Controls
static Expander()
{
PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Down, ":down");
PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Up, ":up");
PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Left, ":left");
PseudoClass(ExpandDirectionProperty, d => d == ExpandDirection.Right, ":right");
PseudoClass<Expander, ExpandDirection>(ExpandDirectionProperty, d => d == ExpandDirection.Down, ":down");
PseudoClass<Expander, ExpandDirection>(ExpandDirectionProperty, d => d == ExpandDirection.Up, ":up");
PseudoClass<Expander, ExpandDirection>(ExpandDirectionProperty, d => d == ExpandDirection.Left, ":left");
PseudoClass<Expander, ExpandDirection>(ExpandDirectionProperty, d => d == ExpandDirection.Right, ":right");
PseudoClass(IsExpandedProperty, ":expanded");
PseudoClass<Expander>(IsExpandedProperty, ":expanded");
IsExpandedProperty.Changed.AddClassHandler<Expander>(x => x.OnIsExpandedChanged);
}

3
src/Avalonia.Controls/Image.cs

@ -25,8 +25,7 @@ namespace Avalonia.Controls
static Image()
{
AffectsRender(SourceProperty);
AffectsRender(StretchProperty);
AffectsRender<Image>(SourceProperty, StretchProperty);
}
/// <summary>

4
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -90,8 +90,8 @@ namespace Avalonia.Controls.Presenters
/// </summary>
static ContentPresenter()
{
AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure(BorderThicknessProperty, PaddingProperty);
AffectsRender<ContentPresenter>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure<ContentPresenter>(BorderThicknessProperty, PaddingProperty);
ContentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.TemplatedParentChanged);

2
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -72,7 +72,7 @@ namespace Avalonia.Controls.Presenters
{
ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>(x => x.ChildChanged);
AffectsArrange(OffsetProperty);
AffectsArrange<ScrollContentPresenter>(OffsetProperty);
}
/// <summary>

2
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -38,7 +38,7 @@ namespace Avalonia.Controls.Presenters
static TextPresenter()
{
AffectsRender(PasswordCharProperty);
AffectsRender<TextPresenter>(PasswordCharProperty);
}
public TextPresenter()

2
src/Avalonia.Controls/Primitives/AccessText.cs

@ -28,7 +28,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static AccessText()
{
AffectsRender(ShowAccessKeyProperty);
AffectsRender<AccessText>(ShowAccessKeyProperty);
}
/// <summary>

4
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -54,8 +54,8 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static ScrollBar()
{
PseudoClass(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragComplete, RoutingStrategies.Bubble);

6
src/Avalonia.Controls/Primitives/ToggleButton.cs

@ -24,9 +24,9 @@ namespace Avalonia.Controls.Primitives
static ToggleButton()
{
PseudoClass(IsCheckedProperty, c => c == true, ":checked");
PseudoClass(IsCheckedProperty, c => c == false, ":unchecked");
PseudoClass(IsCheckedProperty, c => c == null, ":indeterminate");
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == true, ":checked");
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == false, ":unchecked");
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == null, ":indeterminate");
}
public bool? IsChecked

4
src/Avalonia.Controls/Primitives/Track.cs

@ -39,10 +39,12 @@ namespace Avalonia.Controls.Primitives
static Track()
{
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
ThumbProperty.Changed.AddClassHandler<Track>(x => x.ThumbChanged);
IncreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
DecreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
AffectsArrange(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty);
AffectsArrange<Track>(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty);
}
public double Minimum

6
src/Avalonia.Controls/ProgressBar.cs

@ -33,9 +33,9 @@ namespace Avalonia.Controls
static ProgressBar()
{
PseudoClass(OrientationProperty, o => o == Avalonia.Controls.Orientation.Vertical, ":vertical");
PseudoClass(OrientationProperty, o => o == Avalonia.Controls.Orientation.Horizontal, ":horizontal");
PseudoClass(IsIndeterminateProperty, ":indeterminate");
PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Avalonia.Controls.Orientation.Vertical, ":vertical");
PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Avalonia.Controls.Orientation.Horizontal, ":horizontal");
PseudoClass<ProgressBar>(IsIndeterminateProperty, ":indeterminate");
ValueProperty.Changed.AddClassHandler<ProgressBar>(x => x.ValueChanged);
}

5
src/Avalonia.Controls/Shapes/Shape.cs

@ -30,11 +30,10 @@ namespace Avalonia.Controls.Shapes
private Geometry _renderedGeometry;
bool _calculateTransformOnArrange = false;
static Shape()
{
AffectsMeasure(StretchProperty, StrokeThicknessProperty);
AffectsRender(FillProperty, StrokeProperty, StrokeDashArrayProperty);
AffectsMeasure<Shape>(StretchProperty, StrokeThicknessProperty);
AffectsRender<Shape>(FillProperty, StrokeProperty, StrokeDashArrayProperty);
}
public Geometry DefiningGeometry

2
src/Avalonia.Controls/Slider.cs

@ -42,6 +42,8 @@ namespace Avalonia.Controls
static Slider()
{
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragStartedEvent.AddClassHandler<Slider>(x => x.OnThumbDragStarted, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>(x => x.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble);

4
src/Avalonia.Controls/StackPanel.cs

@ -29,8 +29,8 @@ namespace Avalonia.Controls
/// </summary>
static StackPanel()
{
AffectsMeasure(SpacingProperty);
AffectsMeasure(OrientationProperty);
AffectsMeasure<StackPanel>(SpacingProperty);
AffectsMeasure<StackPanel>(OrientationProperty);
}
/// <summary>

2
src/Avalonia.Controls/TabControl.cs

@ -44,7 +44,7 @@ namespace Avalonia.Controls
{
SelectionModeProperty.OverrideDefaultValue<TabControl>(SelectionMode.AlwaysSelected);
FocusableProperty.OverrideDefaultValue<TabControl>(false);
AffectsMeasure(TabStripPlacementProperty);
AffectsMeasure<TabControl>(TabStripPlacementProperty);
}
/// <summary>

9
src/Avalonia.Controls/TextBlock.cs

@ -99,10 +99,11 @@ namespace Avalonia.Controls
static TextBlock()
{
ClipToBoundsProperty.OverrideDefaultValue<TextBlock>(true);
AffectsRender(ForegroundProperty);
AffectsRender(FontWeightProperty);
AffectsRender(FontSizeProperty);
AffectsRender(FontStyleProperty);
AffectsRender<TextBlock>(
ForegroundProperty,
FontWeightProperty,
FontSizeProperty,
FontStyleProperty);
}
/// <summary>

2
src/Avalonia.Controls/TopLevel.cs

@ -59,7 +59,7 @@ namespace Avalonia.Controls
/// </summary>
static TopLevel()
{
AffectsMeasure(ClientSizeProperty);
AffectsMeasure<TopLevel>(ClientSizeProperty);
}
/// <summary>

2
src/Avalonia.Controls/WrapPanel.cs

@ -30,7 +30,7 @@ namespace Avalonia.Controls
/// </summary>
static WrapPanel()
{
AffectsMeasure(OrientationProperty);
AffectsMeasure<WrapPanel>(OrientationProperty);
}
/// <summary>

6
src/Avalonia.Input/InputElement.cs

@ -168,9 +168,9 @@ namespace Avalonia.Input
PointerReleasedEvent.AddClassHandler<InputElement>(x => x.OnPointerReleased);
PointerWheelChangedEvent.AddClassHandler<InputElement>(x => x.OnPointerWheelChanged);
PseudoClass(IsEnabledCoreProperty, x => !x, ":disabled");
PseudoClass(IsFocusedProperty, ":focus");
PseudoClass(IsPointerOverProperty, ":pointerover");
PseudoClass<InputElement, bool>(IsEnabledCoreProperty, x => !x, ":disabled");
PseudoClass<InputElement>(IsFocusedProperty, ":focus");
PseudoClass<InputElement>(IsPointerOverProperty, ":pointerover");
}
/// <summary>

68
src/Avalonia.Layout/Layoutable.cs

@ -140,7 +140,7 @@ namespace Avalonia.Layout
/// </summary>
static Layoutable()
{
AffectsMeasure(
AffectsMeasure<Layoutable>(
IsVisibleProperty,
WidthProperty,
HeightProperty,
@ -427,11 +427,32 @@ namespace Avalonia.Layout
/// After a call to this method in a control's static constructor, any change to the
/// property will cause <see cref="InvalidateMeasure"/> to be called on the element.
/// </remarks>
[Obsolete("Use AffectsMeasure<T> and specify the control type.")]
protected static void AffectsMeasure(params AvaloniaProperty[] properties)
{
AffectsMeasure<Layoutable>(properties);
}
/// <summary>
/// Marks a property as affecting the control's measurement.
/// </summary>
/// <typeparam name="T">The control which the property affects.</typeparam>
/// <param name="properties">The properties.</param>
/// <remarks>
/// After a call to this method in a control's static constructor, any change to the
/// property will cause <see cref="InvalidateMeasure"/> to be called on the element.
/// </remarks>
protected static void AffectsMeasure<T>(params AvaloniaProperty[] properties)
where T : class, ILayoutable
{
void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as T)?.InvalidateMeasure();
}
foreach (var property in properties)
{
property.Changed.Subscribe(AffectsMeasureInvalidate);
property.Changed.Subscribe(Invalidate);
}
}
@ -443,11 +464,32 @@ namespace Avalonia.Layout
/// After a call to this method in a control's static constructor, any change to the
/// property will cause <see cref="InvalidateArrange"/> to be called on the element.
/// </remarks>
[Obsolete("Use AffectsArrange<T> and specify the control type.")]
protected static void AffectsArrange(params AvaloniaProperty[] properties)
{
AffectsArrange<Layoutable>(properties);
}
/// <summary>
/// Marks a property as affecting the control's arrangement.
/// </summary>
/// <typeparam name="T">The control which the property affects.</typeparam>
/// <param name="properties">The properties.</param>
/// <remarks>
/// After a call to this method in a control's static constructor, any change to the
/// property will cause <see cref="InvalidateArrange"/> to be called on the element.
/// </remarks>
protected static void AffectsArrange<T>(params AvaloniaProperty[] properties)
where T : class, ILayoutable
{
void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as T)?.InvalidateArrange();
}
foreach (var property in properties)
{
property.Changed.Subscribe(AffectsArrangeInvalidate);
property.Changed.Subscribe(Invalidate);
}
}
@ -632,26 +674,6 @@ namespace Avalonia.Layout
base.OnVisualParentChanged(oldParent, newParent);
}
/// <summary>
/// Calls <see cref="InvalidateMeasure"/> on the control on which a property changed.
/// </summary>
/// <param name="e">The event args.</param>
private static void AffectsMeasureInvalidate(AvaloniaPropertyChangedEventArgs e)
{
ILayoutable control = e.Sender as ILayoutable;
control?.InvalidateMeasure();
}
/// <summary>
/// Calls <see cref="InvalidateArrange"/> on the control on which a property changed.
/// </summary>
/// <param name="e">The event args.</param>
private static void AffectsArrangeInvalidate(AvaloniaPropertyChangedEventArgs e)
{
ILayoutable control = e.Sender as ILayoutable;
control?.InvalidateArrange();
}
/// <summary>
/// Tests whether any of a <see cref="Rect"/>'s properties include negative values,
/// a NaN or Infinity.

45
src/Avalonia.Styling/StyledElement.cs

@ -493,22 +493,53 @@ namespace Avalonia
/// </summary>
/// <param name="property">The property.</param>
/// <param name="className">The pseudo-class.</param>
[Obsolete("Use PseudoClass<TOwner> and specify the control type.")]
protected static void PseudoClass(AvaloniaProperty<bool> property, string className)
{
PseudoClass(property, x => x, className);
PseudoClass<StyledElement>(property, className);
}
/// <summary>
/// Adds a pseudo-class to be set when a property is true.
/// </summary>
/// <typeparam name="TOwner">The type to apply the pseudo-class to.</typeparam>
/// <param name="property">The property.</param>
/// <param name="className">The pseudo-class.</param>
protected static void PseudoClass<TOwner>(AvaloniaProperty<bool> property, string className)
where TOwner : class, IStyledElement
{
PseudoClass<TOwner, bool>(property, x => x, className);
}
/// <summary>
/// Adds a pseudo-class to be set when a property equals a certain value.
/// </summary>
/// <typeparam name="TProperty">The type of the property.</typeparam>
/// <param name="property">The property.</param>
/// <param name="selector">Returns a boolean value based on the property value.</param>
/// <param name="className">The pseudo-class.</param>
[Obsolete("Use PseudoClass<TOwner, TProperty> and specify the control type.")]
protected static void PseudoClass<TProperty>(
AvaloniaProperty<TProperty> property,
Func<TProperty, bool> selector,
string className)
{
PseudoClass<StyledElement, TProperty>(property, selector, className);
}
/// <summary>
/// Adds a pseudo-class to be set when a property equals a certain value.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <typeparam name="TProperty">The type of the property.</typeparam>
/// <typeparam name="TOwner">The type to apply the pseudo-class to.</typeparam>
/// <param name="property">The property.</param>
/// <param name="selector">Returns a boolean value based on the property value.</param>
/// <param name="className">The pseudo-class.</param>
protected static void PseudoClass<T>(
AvaloniaProperty<T> property,
Func<T, bool> selector,
protected static void PseudoClass<TOwner, TProperty>(
AvaloniaProperty<TProperty> property,
Func<TProperty, bool> selector,
string className)
where TOwner : class, IStyledElement
{
Contract.Requires<ArgumentNullException>(property != null);
Contract.Requires<ArgumentNullException>(selector != null);
@ -520,10 +551,10 @@ namespace Avalonia
}
property.Changed.Merge(property.Initialized)
.Where(e => e.Sender is StyledElement)
.Where(e => e.Sender is TOwner)
.Subscribe(e =>
{
if (selector((T)e.NewValue))
if (selector((TProperty)e.NewValue))
{
((StyledElement)e.Sender).PseudoClasses.Add(className);
}

36
src/Avalonia.Visuals/Visual.cs

@ -100,7 +100,7 @@ namespace Avalonia
/// </summary>
static Visual()
{
AffectsRender(
AffectsRender<Visual>(
BoundsProperty,
ClipProperty,
ClipToBoundsProperty,
@ -320,11 +320,34 @@ namespace Avalonia
/// on the control which when changed should cause a redraw. This is similar to WPF's
/// FrameworkPropertyMetadata.AffectsRender flag.
/// </remarks>
[Obsolete("Use AffectsRender<T> and specify the control type.")]
protected static void AffectsRender(params AvaloniaProperty[] properties)
{
AffectsRender<Visual>(properties);
}
/// <summary>
/// Indicates that a property change should cause <see cref="InvalidateVisual"/> to be
/// called.
/// </summary>
/// <typeparam name="T">The control which the property affects.</typeparam>
/// <param name="properties">The properties.</param>
/// <remarks>
/// This method should be called in a control's static constructor with each property
/// on the control which when changed should cause a redraw. This is similar to WPF's
/// FrameworkPropertyMetadata.AffectsRender flag.
/// </remarks>
protected static void AffectsRender<T>(params AvaloniaProperty[] properties)
where T : class, IVisual
{
void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as T)?.InvalidateVisual();
}
foreach (var property in properties)
{
property.Changed.Subscribe(AffectsRenderInvalidate);
property.Changed.Subscribe(Invalidate);
}
}
@ -412,15 +435,6 @@ namespace Avalonia
RaisePropertyChanged(VisualParentProperty, oldParent, newParent, BindingPriority.LocalValue);
}
/// <summary>
/// Called when a property changes that should invalidate the visual.
/// </summary>
/// <param name="e">The event args.</param>
private static void AffectsRenderInvalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as Visual)?.InvalidateVisual();
}
/// <summary>
/// Gets the visual offset from the specified ancestor.
/// </summary>

Loading…
Cancel
Save