Browse Source

Add support for property navigation from setter directly.

pull/7860/head
Dariusz Komosiński 5 years ago
parent
commit
9b8d78e66a
  1. 10
      src/Avalonia.Base/StyledPropertyBase.cs
  2. 5
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs
  3. 43
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  4. 3
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ResourceSetterViewModel.cs
  5. 48
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
  6. 24
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs

10
src/Avalonia.Base/StyledPropertyBase.cs

@ -159,9 +159,9 @@ namespace Avalonia
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void Accept<TData>(IAvaloniaPropertyVisitor<TData> vistor, ref TData data) public override void Accept<TData>(IAvaloniaPropertyVisitor<TData> visitor, ref TData data)
{ {
vistor.Visit(this, ref data); visitor.Visit(this, ref data);
} }
/// <summary> /// <summary>
@ -242,11 +242,5 @@ namespace Avalonia
_ = type ?? throw new ArgumentNullException(nameof(type)); _ = type ?? throw new ArgumentNullException(nameof(type));
return GetMetadata(type).DefaultValue; return GetMetadata(type).DefaultValue;
} }
[DebuggerHidden]
private Func<IAvaloniaObject, TValue, TValue> Cast<THost>(Func<THost, TValue, TValue> validate)
{
return (o, v) => validate((THost)o, v);
}
} }
} }

5
src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs

@ -14,11 +14,13 @@ namespace Avalonia.Diagnostics.ViewModels
case Binding binding: case Binding binding:
Path = binding.Path; Path = binding.Path;
Tint = Brushes.CornflowerBlue; Tint = Brushes.CornflowerBlue;
ValueTypeTooltip = "Reflection Binding";
break; break;
case CompiledBindingExtension binding: case CompiledBindingExtension binding:
Path = binding.Path.ToString(); Path = binding.Path.ToString();
Tint = Brushes.DarkGreen; Tint = Brushes.DarkGreen;
ValueTypeTooltip = "Compiled Binding";
break; break;
case TemplateBinding binding: case TemplateBinding binding:
@ -32,6 +34,7 @@ namespace Avalonia.Diagnostics.ViewModels
} }
Tint = Brushes.OrangeRed; Tint = Brushes.OrangeRed;
ValueTypeTooltip = "Template Binding";
break; break;
default: default:
@ -40,6 +43,8 @@ namespace Avalonia.Diagnostics.ViewModels
} }
public IBrush Tint { get; } public IBrush Tint { get; }
public string ValueTypeTooltip { get; }
public string Path { get; } public string Path { get; }

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

@ -155,31 +155,19 @@ namespace Avalonia.Diagnostics.ViewModels
public object? SelectedEntity public object? SelectedEntity
{ {
get => _selectedEntity; get => _selectedEntity;
set set => RaiseAndSetIfChanged(ref _selectedEntity, value);
{
RaiseAndSetIfChanged(ref _selectedEntity, value);
}
} }
public string? SelectedEntityName public string? SelectedEntityName
{ {
get => _selectedEntityName; get => _selectedEntityName;
set set => RaiseAndSetIfChanged(ref _selectedEntityName, value);
{
RaiseAndSetIfChanged(ref _selectedEntityName, value);
}
} }
public string? SelectedEntityType public string? SelectedEntityType
{ {
get => _selectedEntityType; get => _selectedEntityType;
set set => RaiseAndSetIfChanged(ref _selectedEntityType, value);
{
RaiseAndSetIfChanged(ref _selectedEntityType, value);
}
} }
public PropertyViewModel? SelectedProperty public PropertyViewModel? SelectedProperty
@ -502,6 +490,31 @@ namespace Avalonia.Diagnostics.ViewModels
inpc2.PropertyChanged += ControlPropertyChanged; inpc2.PropertyChanged += ControlPropertyChanged;
} }
} }
internal void SelectProperty(AvaloniaProperty property)
{
SelectedProperty = null;
if (SelectedEntity != _avaloniaObject)
{
NavigateToProperty(_avaloniaObject, (_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString());
}
if (PropertiesView is null)
{
return;
}
foreach (object o in PropertiesView)
{
if (o is AvaloniaPropertyViewModel propertyVm && propertyVm.Property == property)
{
SelectedProperty = propertyVm;
break;
}
}
}
internal void UpdatePropertiesView(bool showImplementedInterfaces) internal void UpdatePropertiesView(bool showImplementedInterfaces)
{ {

3
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ResourceSetterViewModel.cs

@ -7,11 +7,14 @@ namespace Avalonia.Diagnostics.ViewModels
public object Key { get; } public object Key { get; }
public IBrush Tint { get; } public IBrush Tint { get; }
public string ValueTypeTooltip { get; }
public ResourceSetterViewModel(AvaloniaProperty property, object resourceKey, object? resourceValue, bool isDynamic) : base(property, resourceValue) public ResourceSetterViewModel(AvaloniaProperty property, object resourceKey, object? resourceValue, bool isDynamic) : base(property, resourceValue)
{ {
Key = resourceKey; Key = resourceKey;
Tint = isDynamic ? Brushes.Orange : Brushes.Brown; Tint = isDynamic ? Brushes.Orange : Brushes.Brown;
ValueTypeTooltip = isDynamic ? "Dynamic Resource" : "Static Resource";
} }
public void CopyResourceKey() public void CopyResourceKey()

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

@ -44,7 +44,9 @@
UseWholeWordFilter="{Binding UseWholeWordFilter}" UseWholeWordFilter="{Binding UseWholeWordFilter}"
UseRegexFilter="{Binding UseRegexFilter}"/> UseRegexFilter="{Binding UseRegexFilter}"/>
<DataGrid Items="{Binding PropertiesView}" <DataGrid
x:Name="DataGrid"
Items="{Binding PropertiesView}"
Grid.Row="2" Grid.Row="2"
BorderThickness="0" BorderThickness="0"
RowBackground="Transparent" RowBackground="Transparent"
@ -129,6 +131,18 @@
</Expander.Header> </Expander.Header>
<ItemsControl Margin="20,0,0,0" Grid.Row="1" Items="{Binding Setters}"> <ItemsControl Margin="20,0,0,0" Grid.Row="1" Items="{Binding Setters}">
<ItemsControl.Styles>
<Style Selector="TextBlock.property-name">
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Background" Value="Transparent" />
</Style>
<Style Selector="TextBlock.property-name:pointerover">
<Setter Property="TextDecorations" Value="Underline" />
</Style>
</ItemsControl.Styles>
<ItemsControl.DataTemplates> <ItemsControl.DataTemplates>
<DataTemplate DataType="IBrush"> <DataTemplate DataType="IBrush">
@ -138,6 +152,17 @@
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="Color">
<StackPanel Orientation="Horizontal" Spacing="2">
<Border BorderThickness="1" BorderBrush="Black" Width="8" Height="8">
<Border.Background>
<SolidColorBrush Color="{Binding}" />
</Border.Background>
</Border>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="vm:BindingSetterViewModel"> <DataTemplate DataType="vm:BindingSetterViewModel">
<Panel Opacity="{Binding IsActive, Converter={StaticResource BoolToOpacity}}" IsVisible="{Binding IsVisible}" HorizontalAlignment="Left"> <Panel Opacity="{Binding IsActive, Converter={StaticResource BoolToOpacity}}" IsVisible="{Binding IsVisible}" HorizontalAlignment="Left">
<Panel.ContextMenu> <Panel.ContextMenu>
@ -147,10 +172,10 @@
</ContextMenu> </ContextMenu>
</Panel.ContextMenu> </Panel.ContextMenu>
<StackPanel Orientation="Horizontal" Spacing="2"> <StackPanel Orientation="Horizontal" Spacing="2">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" /> <TextBlock Classes="property-name" PointerPressed="PropertyNamePressed" Text="{Binding Name}" />
<TextBlock Text=":" /> <TextBlock Text=":" />
<TextBlock>{</TextBlock> <TextBlock>{</TextBlock>
<Rectangle Height="8" Width="8" VerticalAlignment="Center" Fill="{Binding Tint}"/> <Rectangle Height="8" Width="8" VerticalAlignment="Center" Fill="{Binding Tint}" ToolTip.Tip="{Binding ValueTypeTooltip}"/>
<TextBlock Text="{Binding Path}" /> <TextBlock Text="{Binding Path}" />
<TextBlock>}</TextBlock> <TextBlock>}</TextBlock>
</StackPanel> </StackPanel>
@ -158,17 +183,6 @@
</Panel> </Panel>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="Color">
<StackPanel Orientation="Horizontal" Spacing="2">
<Border BorderThickness="1" BorderBrush="Black" Width="8" Height="8">
<Border.Background>
<SolidColorBrush Color="{Binding}" />
</Border.Background>
</Border>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="vm:ResourceSetterViewModel"> <DataTemplate DataType="vm:ResourceSetterViewModel">
<Panel Opacity="{Binding IsActive, Converter={StaticResource BoolToOpacity}}" IsVisible="{Binding IsVisible}" HorizontalAlignment="Left"> <Panel Opacity="{Binding IsActive, Converter={StaticResource BoolToOpacity}}" IsVisible="{Binding IsVisible}" HorizontalAlignment="Left">
<Panel.ContextMenu> <Panel.ContextMenu>
@ -179,11 +193,11 @@
</ContextMenu> </ContextMenu>
</Panel.ContextMenu> </Panel.ContextMenu>
<StackPanel Orientation="Horizontal" Spacing="2" HorizontalAlignment="Left"> <StackPanel Orientation="Horizontal" Spacing="2" HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" /> <TextBlock Classes="property-name" PointerPressed="PropertyNamePressed" Text="{Binding Name}" />
<TextBlock Text=":" /> <TextBlock Text=":" />
<ContentControl Content="{Binding Value}"/> <ContentControl Content="{Binding Value}"/>
<TextBlock>(</TextBlock> <TextBlock>(</TextBlock>
<Ellipse Height="8" Width="8" VerticalAlignment="Center" Fill="{Binding Tint}"/> <Ellipse Height="8" Width="8" VerticalAlignment="Center" Fill="{Binding Tint}" ToolTip.Tip="{Binding ValueTypeTooltip}"/>
<TextBlock FontStyle="Italic" Text="{Binding Key}" /> <TextBlock FontStyle="Italic" Text="{Binding Key}" />
<TextBlock>)</TextBlock> <TextBlock>)</TextBlock>
</StackPanel> </StackPanel>
@ -200,7 +214,7 @@
</ContextMenu> </ContextMenu>
</Panel.ContextMenu> </Panel.ContextMenu>
<StackPanel Orientation="Horizontal" Spacing="2"> <StackPanel Orientation="Horizontal" Spacing="2">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" /> <TextBlock Classes="property-name" PointerPressed="PropertyNamePressed" Text="{Binding Name}" />
<TextBlock Text=":" /> <TextBlock Text=":" />
<ContentControl Content="{Binding Value}"/> <ContentControl Content="{Binding Value}"/>
</StackPanel> </StackPanel>

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

@ -7,9 +7,13 @@ namespace Avalonia.Diagnostics.Views
{ {
internal class ControlDetailsView : UserControl internal class ControlDetailsView : UserControl
{ {
private DataGrid _dataGrid;
public ControlDetailsView() public ControlDetailsView()
{ {
InitializeComponent(); InitializeComponent();
_dataGrid = this.GetControl<DataGrid>("DataGrid");
} }
private void InitializeComponent() private void InitializeComponent()
@ -25,5 +29,25 @@ namespace Avalonia.Diagnostics.Views
} }
} }
private void PropertyNamePressed(object sender, PointerPressedEventArgs e)
{
var mainVm = (ControlDetailsViewModel?) DataContext;
if (mainVm is null)
{
return;
}
if (sender is Control control && control.DataContext is SetterViewModel setterVm)
{
mainVm.SelectProperty(setterVm.Property);
if (mainVm.SelectedProperty is not null)
{
_dataGrid.ScrollIntoView(mainVm.SelectedProperty, null);
}
}
}
} }
} }

Loading…
Cancel
Save