#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 { /// Additional properties that can be attached to Avalonia objects public static class Properties { #region class InvalidateMeasureOnChangeObserver /// /// Invalidates the calculated measurement of the control that is reporting /// a change to the property value /// private class InvalidateMeasureOnChangeObserver : IObserver> { /// The one and only instance you need public static readonly InvalidateMeasureOnChangeObserver Instance = new(); /// Called after all observers have been notified successfully public void OnCompleted() {} /// Reports when the observed control encountered an error /// Error the observed control has encountered public void OnError(Exception error) {} /// Reports the updated value of the property to the observer /// New value the property has assumed public void OnNext(AvaloniaPropertyChangedEventArgs value) { if(value.Sender is Control senderAsControl) { senderAsControl.InvalidateMeasure(); } } } #endregion // class InvalidateMeasureOnChangeObserver /// /// Invalidates the object's measured size of a control and triggers a new layout pass /// /// /// /// 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. /// /// /// 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: /// /// /// /// <Border /// CornerRadius="4" /// Padding="4,0" /// HorizontalAlignment="Center" /// nuclex:Properties.InvalidateMeasureOnChange="{Binding Status}" /// > /// <TextBlock /// HorizontalAlignment="Center" /// Text="{Binding Status}" /// /> /// </Border> /// /// /// public static readonly AttachedProperty InvalidateMeasureOnChangeProperty = ( AvaloniaProperty.RegisterAttached( "InvalidateMeasureOnChange", typeof(Properties), defaultValue: null!, inherits: false ) ); /// Initializes all static members of the class static Properties() { InvalidateMeasureOnChangeProperty.Changed.Subscribe(InvalidateMeasureOnChangeObserver.Instance); } /// Reads the value of the 'InvalidateMeasureOnChange' property /// Control from which the property will be read /// The current value of the property attached to the control public static object GetInvalidateMeasureOnChange(Control control) { return control.GetValue(InvalidateMeasureOnChangeProperty); } /// Updates the value of the 'InvalidateMeasureOnChange' property /// Control on which the property will be updated /// New value to assign to the attached property public static void SetInvalidateMeasureOnChange(Control control, object value) { control.SetValue(InvalidateMeasureOnChangeProperty, value); } } } // namespace Nuclex.Avalonia