Browse Source

Merge pull request #5015 from MarchingCube/layout-visualizer

Add support for visualizing layout properties.
pull/5017/head
Dan Walmsley 6 years ago
committed by GitHub
parent
commit
a2d6fbb59c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  2. 190
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs
  3. 179
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
  4. 109
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs
  5. 130
      src/Avalonia.Diagnostics/Diagnostics/Views/ThicknessEditor.cs
  6. 2
      src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml

6
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs

@ -32,6 +32,8 @@ namespace Avalonia.Diagnostics.ViewModels
view.Filter = FilterProperty; view.Filter = FilterProperty;
PropertiesView = view; PropertiesView = view;
Layout = new ControlLayoutViewModel(control);
if (control is INotifyPropertyChanged inpc) if (control is INotifyPropertyChanged inpc)
{ {
inpc.PropertyChanged += ControlPropertyChanged; inpc.PropertyChanged += ControlPropertyChanged;
@ -52,6 +54,8 @@ namespace Avalonia.Diagnostics.ViewModels
get => _selectedProperty; get => _selectedProperty;
set => RaiseAndSetIfChanged(ref _selectedProperty, value); set => RaiseAndSetIfChanged(ref _selectedProperty, value);
} }
public ControlLayoutViewModel Layout { get; }
public void Dispose() public void Dispose()
{ {
@ -112,6 +116,8 @@ namespace Avalonia.Diagnostics.ViewModels
property.Update(); property.Update();
} }
} }
Layout.ControlPropertyChanged(sender, e);
} }
private void ControlPropertyChanged(object sender, PropertyChangedEventArgs e) private void ControlPropertyChanged(object sender, PropertyChangedEventArgs e)

190
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs

@ -0,0 +1,190 @@
using System.ComponentModel;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.ViewModels
{
internal class ControlLayoutViewModel : ViewModelBase
{
private readonly IVisual _control;
private Thickness _marginThickness;
private Thickness _borderThickness;
private Thickness _paddingThickness;
private double _width;
private double _height;
private string _widthConstraint;
private string _heightConstraint;
private bool _updatingFromControl;
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 bool HasPadding { get; }
public bool HasBorder { get; }
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);
}
}
UpdateSize();
UpdateSizeConstraints();
}
private void UpdateSizeConstraints()
{
if (_control is IAvaloniaObject ao)
{
string CreateConstraintInfo(StyledProperty<double> minProperty, StyledProperty<double> maxProperty)
{
if (ao.IsSet(minProperty) || ao.IsSet(maxProperty))
{
var minValue = ao.GetValue(minProperty);
var maxValue = ao.GetValue(maxProperty);
return $"{minValue} < size < {maxValue}";
}
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);
}
}
}
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();
}
}
}
}
finally
{
_updatingFromControl = false;
}
}
private void UpdateSize()
{
var size = _control.Bounds;
Width = size.Width;
Height = size.Height;
}
}
}

179
src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml

@ -1,38 +1,155 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:Avalonia.Diagnostics.Converters" xmlns:conv="clr-namespace:Avalonia.Diagnostics.Converters"
xmlns:local="clr-namespace:Avalonia.Diagnostics.Views"
x:Class="Avalonia.Diagnostics.Views.ControlDetailsView"> x:Class="Avalonia.Diagnostics.Views.ControlDetailsView">
<Grid ColumnDefinitions="*,Auto" RowDefinitions="Auto,*">
<TextBox Grid.Row="0" Grid.Column="0"
BorderThickness="0"
Text="{Binding TreePage.PropertyFilter}"
Watermark="Filter properties" />
<CheckBox Grid.Row="0"
Grid.Column="1"
Content="Regex"
IsChecked="{Binding TreePage.UseRegexFilter}"/>
<DataGrid Items="{Binding PropertiesView}"
Grid.Row="1" Grid.ColumnSpan="2"
BorderThickness="0"
RowBackground="Transparent"
SelectedItem="{Binding SelectedProperty, Mode=TwoWay}"
CanUserResizeColumns="true">
<DataGrid.Columns>
<DataGridTextColumn Header="Property" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}" />
<DataGridTextColumn Header="Priority" Binding="{Binding Priority}" IsReadOnly="True" />
</DataGrid.Columns>
<DataGrid.Styles>
<Style Selector="DataGridRow TextBox">
<Setter Property="SelectionBrush" Value="LightBlue"/>
</Style>
</DataGrid.Styles>
</DataGrid>
<UserControl.Resources>
<SolidColorBrush x:Key="ThicknessBorderBrush" Color="#666666" />
<SolidColorBrush x:Key="SizeGuidelineBrush" Color="#333333" />
<SolidColorBrush x:Key="MarginBackgroundBrush" Color="#D78965" />
<SolidColorBrush x:Key="BorderBackgroundBrush" Color="#E3C381" />
<SolidColorBrush x:Key="PaddingBackgroundBrush" Color="#B8C47F" />
<SolidColorBrush x:Key="SizeBackgroundBrush" Color="#88B2BD" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="local|ThicknessEditor">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{StaticResource ThicknessBorderBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid RowDefinitions="Auto,*,Auto" ColumnDefinitions="Auto,*,Auto">
<Grid.Styles>
<Style Selector="TextBox.thickness-edit">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="2" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="(ScrollViewer.HorizontalScrollBarVisibility)" Value="Disabled" />
<Setter Property="(ScrollViewer.VerticalScrollBarVisibility)" Value="Disabled" />
<Setter Property="IsVisible" Value="{Binding $parent[local:ThicknessEditor].IsPresent}" />
</Style>
</Grid.Styles>
<TextBlock IsVisible="{TemplateBinding IsPresent}" Margin="4,0,0,0" Text="{TemplateBinding Header}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
<TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Left, RelativeSource={RelativeSource TemplatedParent}}" Classes="thickness-edit" />
<TextBox x:Name="Right" Grid.Row="0" Grid.Column="1" Text="{Binding Top, RelativeSource={RelativeSource TemplatedParent}}" Classes="thickness-edit" />
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Right, RelativeSource={RelativeSource TemplatedParent}}" Classes="thickness-edit" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Bottom, RelativeSource={RelativeSource TemplatedParent}}" Classes="thickness-edit" />
<ContentPresenter Grid.Row="1" Grid.Column="1"
Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="local|ThicknessEditor[IsPresent=False]">
<Setter Property="BorderThickness" Value="0" />
</Style>
</UserControl.Styles>
<Grid ColumnDefinitions="*,Auto,280">
<Grid Grid.Column="0" ColumnDefinitions="*,Auto,Auto,Auto" RowDefinitions="Auto,*">
<TextBox Grid.Row="0"
Grid.Column="0"
BorderThickness="0"
Text="{Binding TreePage.PropertyFilter}"
Watermark="Filter properties" />
<CheckBox Grid.Row="0"
Grid.Column="1"
Margin="0,0,4,0"
Content="Regex"
IsChecked="{Binding TreePage.UseRegexFilter}" />
<DataGrid Items="{Binding PropertiesView}"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
BorderThickness="0"
RowBackground="Transparent"
SelectedItem="{Binding SelectedProperty, Mode=TwoWay}"
CanUserResizeColumns="true">
<DataGrid.Columns>
<DataGridTextColumn Header="Property" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}" />
<DataGridTextColumn Header="Priority" Binding="{Binding Priority}" IsReadOnly="True" />
</DataGrid.Columns>
<DataGrid.Styles>
<Style Selector="DataGridRow TextBox">
<Setter Property="SelectionBrush" Value="LightBlue" />
</Style>
</DataGrid.Styles>
</DataGrid>
</Grid>
<GridSplitter Grid.Column="1" />
<Grid Grid.Column="2" RowDefinitions="Auto,*" >
<TextBlock Grid.Row="0" Text="Layout Visualizer" Margin="4" />
<Grid Grid.Row="1" x:Name="LayoutRoot" Margin="8,0,8,8" RowDefinitions="Auto,Auto" ColumnDefinitions="Auto,Auto">
<Border x:Name="VerticalSize" Grid.Row="0" Grid.Column="1" >
<TextBlock VerticalAlignment="Center" FontWeight="Bold"
TextDecorations="{Binding Layout.HeightConstraint, Converter={x:Static local:Converters.HasConstraintConverter}}"
Text="{Binding Layout.Height}"
ToolTip.Tip="{Binding Layout.HeightConstraint}" />
</Border>
<Border x:Name="HorizontalSize" Grid.Row="1" Grid.Column="0" >
<TextBlock HorizontalAlignment="Center" FontWeight="Bold"
TextDecorations="{Binding Layout.WidthConstraint, Converter={x:Static local:Converters.HasConstraintConverter}}"
Text="{Binding Layout.Width}"
ToolTip.Tip="{Binding Layout.WidthConstraint}" />
</Border>
<local:ThicknessEditor Grid.Row="0" Grid.Column="0" Header="margin" VerticalAlignment="Top" HorizontalAlignment="Center" Background="{StaticResource MarginBackgroundBrush}" Thickness="{Binding Layout.MarginThickness}">
<local:ThicknessEditor x:Name="BorderArea" Header="border" Background="{StaticResource BorderBackgroundBrush}" Thickness="{Binding Layout.BorderThickness}" IsPresent="{Binding Layout.HasBorder}">
<local:ThicknessEditor x:Name="PaddingArea" Header="padding" Background="{StaticResource PaddingBackgroundBrush}" Thickness="{Binding Layout.PaddingThickness}" IsPresent="{Binding Layout.HasPadding}">
<Border x:Name="ContentArea" BorderThickness="1" BorderBrush="{StaticResource ThicknessBorderBrush}" MinWidth="100" MinHeight="16" Background="{StaticResource SizeBackgroundBrush}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBlock Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" Text="content" />
</Border>
</local:ThicknessEditor>
</local:ThicknessEditor>
</local:ThicknessEditor>
<Canvas Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2">
<Canvas.Styles>
<Style Selector="Rectangle">
<Setter Property="StrokeDashArray" Value="1,3" />
<Setter Property="Stroke" Value="{StaticResource SizeGuidelineBrush}" />
<Setter Property="StrokeThickness" Value="1" />
</Style>
</Canvas.Styles>
<Rectangle x:Name="HorizontalSizeBegin" />
<Rectangle x:Name="HorizontalSizeEnd" />
<Rectangle x:Name="VerticalSizeBegin" />
<Rectangle x:Name="VerticalSizeEnd" />
</Canvas>
</Grid>
</Grid>
</Grid> </Grid>
</UserControl> </UserControl>

109
src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs

@ -1,10 +1,24 @@
using System;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.Views namespace Avalonia.Diagnostics.Views
{ {
internal class ControlDetailsView : UserControl internal class ControlDetailsView : UserControl
{ {
private ThicknessEditor _borderArea;
private ThicknessEditor _paddingArea;
private Rectangle _horizontalSizeBegin;
private Rectangle _horizontalSizeEnd;
private Rectangle _verticalSizeBegin;
private Rectangle _verticalSizeEnd;
private Grid _layoutRoot;
private Border _horizontalSize;
private Border _verticalSize;
private Border _contentArea;
public ControlDetailsView() public ControlDetailsView()
{ {
InitializeComponent(); InitializeComponent();
@ -13,6 +27,101 @@ namespace Avalonia.Diagnostics.Views
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
_borderArea = this.FindControl<ThicknessEditor>("BorderArea");
_paddingArea = this.FindControl<ThicknessEditor>("PaddingArea");
_horizontalSizeBegin = this.FindControl<Rectangle>("HorizontalSizeBegin");
_horizontalSizeEnd = this.FindControl<Rectangle>("HorizontalSizeEnd");
_verticalSizeBegin = this.FindControl<Rectangle>("VerticalSizeBegin");
_verticalSizeEnd = this.FindControl<Rectangle>("VerticalSizeEnd");
_horizontalSize = this.FindControl<Border>("HorizontalSize");
_verticalSize = this.FindControl<Border>("VerticalSize");
_contentArea = this.FindControl<Border>("ContentArea");
_layoutRoot = this.FindControl<Grid>("LayoutRoot");
void SubscribeToBounds(Visual visual)
{
visual.GetPropertyChangedObservable(TransformedBoundsProperty)
.Subscribe(UpdateSizeGuidelines);
}
SubscribeToBounds(_borderArea);
SubscribeToBounds(_paddingArea);
SubscribeToBounds(_contentArea);
}
private void UpdateSizeGuidelines(AvaloniaPropertyChangedEventArgs e)
{
void UpdateGuidelines(Visual area)
{
if (area.TransformedBounds is TransformedBounds bounds)
{
// Horizontal guideline
{
var sizeArea = TranslateToRoot((_horizontalSize.TransformedBounds ?? default).Bounds.BottomLeft,
_horizontalSize);
var start = TranslateToRoot(bounds.Bounds.BottomLeft, area);
SetPosition(_horizontalSizeBegin, start);
var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
SetPosition(_horizontalSizeEnd, end.WithX(end.X - 1));
var height = sizeArea.Y - start.Y + 2;
_horizontalSizeBegin.Height = height;
_horizontalSizeEnd.Height = height;
}
// Vertical guideline
{
var sizeArea = TranslateToRoot((_verticalSize.TransformedBounds ?? default).Bounds.TopRight, _verticalSize);
var start = TranslateToRoot(bounds.Bounds.TopRight, area);
SetPosition(_verticalSizeBegin, start);
var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
SetPosition(_verticalSizeEnd, end.WithY(end.Y - 1));
var width = sizeArea.X - start.X + 2;
_verticalSizeBegin.Width = width;
_verticalSizeEnd.Width = width;
}
}
}
Point TranslateToRoot(Point point, IVisual from)
{
return from.TranslatePoint(point, _layoutRoot) ?? default;
}
static void SetPosition(Rectangle rect, Point start)
{
Canvas.SetLeft(rect, start.X);
Canvas.SetTop(rect, start.Y);
}
if (_borderArea.IsPresent)
{
UpdateGuidelines(_borderArea);
}
else if (_paddingArea.IsPresent)
{
UpdateGuidelines(_paddingArea);
}
else
{
UpdateGuidelines(_contentArea);
}
} }
} }
} }

130
src/Avalonia.Diagnostics/Diagnostics/Views/ThicknessEditor.cs

@ -0,0 +1,130 @@
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace Avalonia.Diagnostics.Views
{
internal static class Converters
{
public static IValueConverter HasConstraintConverter =
new FuncValueConverter<object, TextDecorationCollection>(ConvertToDecoration);
private static TextDecorationCollection ConvertToDecoration(object arg)
{
return arg != null ? TextDecorations.Underline : null;
}
}
internal class ThicknessEditor : ContentControl
{
public static readonly DirectProperty<ThicknessEditor, Thickness> ThicknessProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, Thickness>(nameof(Thickness), o => o.Thickness,
(o, v) => o.Thickness = v, defaultBindingMode: BindingMode.TwoWay);
public static readonly DirectProperty<ThicknessEditor, string> HeaderProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, string>(nameof(Header), o => o.Header,
(o, v) => o.Header = v);
public static readonly DirectProperty<ThicknessEditor, bool> IsPresentProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, bool>(nameof(Header), o => o.IsPresent,
(o, v) => o.IsPresent = v);
public static readonly DirectProperty<ThicknessEditor, double> LeftProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, double>(nameof(Left), o => o.Left, (o, v) => o.Left = v);
public static readonly DirectProperty<ThicknessEditor, double> TopProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, double>(nameof(Top), o => o.Top, (o, v) => o.Top = v);
public static readonly DirectProperty<ThicknessEditor, double> RightProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, double>(nameof(Right), o => o.Right,
(o, v) => o.Right = v);
public static readonly DirectProperty<ThicknessEditor, double> BottomProperty =
AvaloniaProperty.RegisterDirect<ThicknessEditor, double>(nameof(Bottom), o => o.Bottom,
(o, v) => o.Bottom = v);
private Thickness _thickness;
private string _header;
private bool _isPresent = true;
private double _left;
private double _top;
private double _right;
private double _bottom;
private bool _isUpdatingThickness;
public Thickness Thickness
{
get => _thickness;
set => SetAndRaise(ThicknessProperty, ref _thickness, value);
}
public string Header
{
get => _header;
set => SetAndRaise(HeaderProperty, ref _header, value);
}
public bool IsPresent
{
get => _isPresent;
set => SetAndRaise(IsPresentProperty, ref _isPresent, value);
}
public double Left
{
get => _left;
set => SetAndRaise(LeftProperty, ref _left, value);
}
public double Top
{
get => _top;
set => SetAndRaise(TopProperty, ref _top, value);
}
public double Right
{
get => _right;
set => SetAndRaise(RightProperty, ref _right, value);
}
public double Bottom
{
get => _bottom;
set => SetAndRaise(BottomProperty, ref _bottom, value);
}
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
{
base.OnPropertyChanged(change);
if (change.Property == ThicknessProperty)
{
try
{
_isUpdatingThickness = true;
var value = change.NewValue.GetValueOrDefault<Thickness>();
Left = value.Left;
Top = value.Top;
Right = value.Right;
Bottom = value.Bottom;
}
finally
{
_isUpdatingThickness = false;
}
}
else if (!_isUpdatingThickness &&
(change.Property == LeftProperty || change.Property == TopProperty ||
change.Property == RightProperty || change.Property == BottomProperty))
{
Thickness = new Thickness(Left, Top, Right, Bottom);
}
}
}
}

2
src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml

@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Avalonia.Diagnostics.ViewModels" xmlns:vm="clr-namespace:Avalonia.Diagnostics.ViewModels"
x:Class="Avalonia.Diagnostics.Views.TreePageView"> x:Class="Avalonia.Diagnostics.Views.TreePageView">
<Grid ColumnDefinitions="0.8*,4,*"> <Grid ColumnDefinitions="0.4*,4,0.6*">
<TreeView Name="tree" <TreeView Name="tree"
BorderThickness="0" BorderThickness="0"
Items="{Binding Nodes}" Items="{Binding Nodes}"

Loading…
Cancel
Save