122 lines
4.6 KiB
C#
122 lines
4.6 KiB
C#
#region Apache License 2.0
|
|
/*
|
|
Nuclex Foundation libraries for .NET
|
|
Copyright (C) 2002-2025 Markus Ewald / Nuclex Development Labs
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
#endregion // Apache License 2.0
|
|
|
|
using System;
|
|
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
|
|
namespace Nuclex.Avalonia {
|
|
|
|
/// <summary>Additional properties that can be attached to Avalonia objects</summary>
|
|
public static class Properties {
|
|
|
|
#region class InvalidateMeasureOnChangeObserver
|
|
|
|
/// <summary>
|
|
/// Invalidates the calculated measurement of the control that is reporting
|
|
/// a change to the property value
|
|
/// </summary>
|
|
private class InvalidateMeasureOnChangeObserver :
|
|
IObserver<AvaloniaPropertyChangedEventArgs<object>> {
|
|
|
|
/// <summary>The one and only instance you need</summary>
|
|
public static readonly InvalidateMeasureOnChangeObserver Instance = new();
|
|
|
|
/// <summary>Called after all observers have been notified successfully</summary>
|
|
public void OnCompleted() {}
|
|
|
|
/// <summary>Reports when the observed control encountered an error</summary>
|
|
/// <param name="error">Error the observed control has encountered</param>
|
|
public void OnError(Exception error) {}
|
|
|
|
/// <summary>Reports the updated value of the property to the observer</summary>
|
|
/// <param name="value">New value the property has assumed</param>
|
|
public void OnNext(AvaloniaPropertyChangedEventArgs<object> value) {
|
|
if(value.Sender is Control senderAsControl) {
|
|
senderAsControl.InvalidateMeasure();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endregion // class InvalidateMeasureOnChangeObserver
|
|
|
|
/// <summary>
|
|
/// Invalidates the object's measured size of a control and triggers a new layout pass
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// If, for some reason, an Avalonia control whose size depends on a data-bound value
|
|
/// (for example, a <Border /> that holds a <TextBlock /gt; that uses data
|
|
/// binding) does not update its own size, that is an Avalonia bug.
|
|
/// </para>
|
|
/// <para>
|
|
/// By attaching this property to the misbehaving control and data-binding its value
|
|
/// to the trigger that should cause a reevaluation of its dimensions, you can work
|
|
/// around the issue:
|
|
/// </para>
|
|
/// <example>
|
|
/// <code>
|
|
/// <Border
|
|
/// CornerRadius="4"
|
|
/// Padding="4,0"
|
|
/// HorizontalAlignment="Center"
|
|
/// nuclex:Properties.InvalidateMeasureOnChange="{Binding Status}"
|
|
/// >
|
|
/// <TextBlock
|
|
/// HorizontalAlignment="Center"
|
|
/// Text="{Binding Status}"
|
|
/// />
|
|
/// </Border>
|
|
/// </code>
|
|
/// </example>
|
|
/// </remarks>
|
|
public static readonly AttachedProperty<object> InvalidateMeasureOnChangeProperty = (
|
|
AvaloniaProperty.RegisterAttached<Control, object>(
|
|
"InvalidateMeasureOnChange",
|
|
typeof(Properties),
|
|
defaultValue: null!,
|
|
inherits: false
|
|
)
|
|
);
|
|
|
|
/// <summary>Initializes all static members of the class</summary>
|
|
static Properties() {
|
|
InvalidateMeasureOnChangeProperty.Changed.Subscribe(InvalidateMeasureOnChangeObserver.Instance);
|
|
}
|
|
|
|
/// <summary>Reads the value of the 'InvalidateMeasureOnChange' property</summary>
|
|
/// <param name="control">Control from which the property will be read</param>
|
|
/// <returns>The current value of the property attached to the control</returns>
|
|
public static object GetInvalidateMeasureOnChange(Control control) {
|
|
return control.GetValue(InvalidateMeasureOnChangeProperty);
|
|
}
|
|
|
|
/// <summary>Updates the value of the 'InvalidateMeasureOnChange' property</summary>
|
|
/// <param name="control">Control on which the property will be updated</param>
|
|
/// <param name="value">New value to assign to the attached property</param>
|
|
public static void SetInvalidateMeasureOnChange(Control control, object value) {
|
|
control.SetValue(InvalidateMeasureOnChangeProperty, value);
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace Nuclex.Avalonia
|