| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using System;
- using System.ComponentModel;
- using System.Text;
- using Avalonia.Controls;
- using Avalonia.Layout;
- using Avalonia.VisualTree;
- namespace Avalonia.Diagnostics.ViewModels
- {
- internal class ControlLayoutViewModel : ViewModelBase
- {
- private readonly IVisual _control;
- private Thickness _borderThickness;
- private double _height;
- private string? _heightConstraint;
- private HorizontalAlignment _horizontalAlignment;
- private Thickness _marginThickness;
- private Thickness _paddingThickness;
- private bool _updatingFromControl;
- private VerticalAlignment _verticalAlignment;
- private double _width;
- private string? _widthConstraint;
- public ControlLayoutViewModel(IVisual control)
- {
- _control = control;
- HasPadding = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Decorator.PaddingProperty);
- HasBorder = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Border.BorderThicknessProperty);
- if (control is AvaloniaObject ao)
- {
- MarginThickness = ao.GetValue(Layoutable.MarginProperty);
- if (HasPadding)
- {
- PaddingThickness = ao.GetValue(Decorator.PaddingProperty);
- }
- if (HasBorder)
- {
- BorderThickness = ao.GetValue(Border.BorderThicknessProperty);
- }
- HorizontalAlignment = ao.GetValue(Layoutable.HorizontalAlignmentProperty);
- VerticalAlignment = ao.GetValue(Layoutable.VerticalAlignmentProperty);
- }
- UpdateSize();
- UpdateSizeConstraints();
- }
- public Thickness MarginThickness
- {
- get => _marginThickness;
- set => RaiseAndSetIfChanged(ref _marginThickness, value);
- }
- public Thickness BorderThickness
- {
- get => _borderThickness;
- set => RaiseAndSetIfChanged(ref _borderThickness, value);
- }
- public Thickness PaddingThickness
- {
- get => _paddingThickness;
- set => RaiseAndSetIfChanged(ref _paddingThickness, value);
- }
- public double Width
- {
- get => _width;
- private set => RaiseAndSetIfChanged(ref _width, value);
- }
- public double Height
- {
- get => _height;
- private set => RaiseAndSetIfChanged(ref _height, value);
- }
- public string? WidthConstraint
- {
- get => _widthConstraint;
- private set => RaiseAndSetIfChanged(ref _widthConstraint, value);
- }
- public string? HeightConstraint
- {
- get => _heightConstraint;
- private set => RaiseAndSetIfChanged(ref _heightConstraint, value);
- }
- public HorizontalAlignment HorizontalAlignment
- {
- get => _horizontalAlignment;
- private set => RaiseAndSetIfChanged(ref _horizontalAlignment, value);
- }
- public VerticalAlignment VerticalAlignment
- {
- get => _verticalAlignment;
- private set => RaiseAndSetIfChanged(ref _verticalAlignment, value);
- }
- public bool HasPadding { get; }
- public bool HasBorder { get; }
- private void UpdateSizeConstraints()
- {
- if (_control is IAvaloniaObject ao)
- {
- string? CreateConstraintInfo(StyledProperty<double> minProperty, StyledProperty<double> maxProperty)
- {
- bool hasMin = ao.IsSet(minProperty);
- bool hasMax = ao.IsSet(maxProperty);
- if (hasMin || hasMax)
- {
- var builder = new StringBuilder();
- if (hasMin)
- {
- var minValue = ao.GetValue(minProperty);
- builder.AppendFormat("Min: {0}", Math.Round(minValue, 2));
- builder.AppendLine();
- }
- if (hasMax)
- {
- var maxValue = ao.GetValue(maxProperty);
- builder.AppendFormat("Max: {0}", Math.Round(maxValue, 2));
- }
- return builder.ToString();
- }
- return null;
- }
- WidthConstraint = CreateConstraintInfo(Layoutable.MinWidthProperty, Layoutable.MaxWidthProperty);
- HeightConstraint = CreateConstraintInfo(Layoutable.MinHeightProperty, Layoutable.MaxHeightProperty);
- }
- }
- protected override void OnPropertyChanged(PropertyChangedEventArgs e)
- {
- base.OnPropertyChanged(e);
- if (_updatingFromControl)
- {
- return;
- }
- if (_control is AvaloniaObject ao)
- {
- if (e.PropertyName == nameof(MarginThickness))
- {
- ao.SetValue(Layoutable.MarginProperty, MarginThickness);
- }
- else if (HasPadding && e.PropertyName == nameof(PaddingThickness))
- {
- ao.SetValue(Decorator.PaddingProperty, PaddingThickness);
- }
- else if (HasBorder && e.PropertyName == nameof(BorderThickness))
- {
- ao.SetValue(Border.BorderThicknessProperty, BorderThickness);
- }
- else if (e.PropertyName == nameof(HorizontalAlignment))
- {
- ao.SetValue(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment);
- }
- else if (e.PropertyName == nameof(VerticalAlignment))
- {
- ao.SetValue(Layoutable.VerticalAlignmentProperty, VerticalAlignment);
- }
- }
- }
- public void ControlPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
- {
- try
- {
- _updatingFromControl = true;
- if (e.Property == Visual.BoundsProperty)
- {
- UpdateSize();
- }
- else
- {
- if (_control is IAvaloniaObject ao)
- {
- if (e.Property == Layoutable.MarginProperty)
- {
- MarginThickness = ao.GetValue(Layoutable.MarginProperty);
- }
- else if (e.Property == Decorator.PaddingProperty)
- {
- PaddingThickness = ao.GetValue(Decorator.PaddingProperty);
- }
- else if (e.Property == Border.BorderThicknessProperty)
- {
- BorderThickness = ao.GetValue(Border.BorderThicknessProperty);
- }
- else if (e.Property == Layoutable.MinWidthProperty ||
- e.Property == Layoutable.MaxWidthProperty ||
- e.Property == Layoutable.MinHeightProperty ||
- e.Property == Layoutable.MaxHeightProperty)
- {
- UpdateSizeConstraints();
- }
- else if (e.Property == Layoutable.HorizontalAlignmentProperty)
- {
- HorizontalAlignment = ao.GetValue(Layoutable.HorizontalAlignmentProperty);
- }
- else if (e.Property == Layoutable.VerticalAlignmentProperty)
- {
- VerticalAlignment = ao.GetValue(Layoutable.VerticalAlignmentProperty);
- }
- }
- }
- }
- finally
- {
- _updatingFromControl = false;
- }
- }
- private void UpdateSize()
- {
- var size = _control.Bounds;
- Width = Math.Round(size.Width, 2);
- Height = Math.Round(size.Height, 2);
- }
- }
- }
|