Browse Source

Merge pull request #8445 from pr8x/devtools-nav-properties

Some QOL improvements for DevTools
pull/8446/head
Max Katz 4 years ago
committed by GitHub
parent
commit
64dd2f49d1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 108
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  2. 6
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
  3. 2
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs

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

@ -113,6 +113,8 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
public bool CanNavigateToParentProperty => _selectedEntitiesStack.Count >= 1;
private (object resourceKey, bool isDynamic)? GetResourceInfo(object? value)
{
if (value is StaticResourceExtension staticResource)
@ -415,7 +417,14 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
public void ApplySelectedProperty()
private static IEnumerable<PropertyInfo> GetAllPublicProperties(Type type)
{
return type
.GetProperties()
.Concat(type.GetInterfaces().SelectMany(i => i.GetProperties()));
}
public void NavigateToSelectedProperty()
{
var selectedProperty = SelectedProperty;
var selectedEntity = SelectedEntity;
@ -423,72 +432,103 @@ namespace Avalonia.Diagnostics.ViewModels
if (selectedEntity == null
|| selectedProperty == null
|| selectedProperty.PropertyType == typeof(string)
|| selectedProperty.PropertyType.IsValueType
)
|| selectedProperty.PropertyType.IsValueType)
return;
object? property;
if (selectedProperty.Key is AvaloniaProperty avaloniaProperty)
object? property = null;
switch (selectedProperty)
{
property = (_selectedEntity as IControl)?.GetValue(avaloniaProperty);
case AvaloniaPropertyViewModel avaloniaProperty:
property = (_selectedEntity as IControl)?.GetValue(avaloniaProperty.Property);
break;
case ClrPropertyViewModel clrProperty:
{
property = GetAllPublicProperties(selectedEntity.GetType())
.FirstOrDefault(pi => clrProperty.Property == pi)?
.GetValue(selectedEntity);
break;
}
}
else
if (property == null)
return;
_selectedEntitiesStack.Push((Name:selectedEntityName!, Entry:selectedEntity));
var propertyName = selectedProperty.Name;
//Strip out interface names
if (propertyName.LastIndexOf('.') is var p && p != -1)
{
property = selectedEntity.GetType().GetProperties()
.FirstOrDefault(pi => pi.Name == selectedProperty.Name
&& pi.DeclaringType == selectedProperty.DeclaringType
&& pi.PropertyType.Name == selectedProperty.PropertyType.Name)
?.GetValue(selectedEntity);
propertyName = propertyName.Substring(p + 1);
}
if (property == null) return;
_selectedEntitiesStack.Push((Name:selectedEntityName!,Entry:selectedEntity));
NavigateToProperty(property, selectedProperty.Name);
NavigateToProperty(property, selectedEntityName + "." + propertyName);
RaisePropertyChanged(nameof(CanNavigateToParentProperty));
}
public void ApplyParentProperty()
public void NavigateToParentProperty()
{
if (_selectedEntitiesStack.Any())
if (_selectedEntitiesStack.Count > 0)
{
var property = _selectedEntitiesStack.Pop();
NavigateToProperty(property.Entry, property.Name);
RaisePropertyChanged(nameof(CanNavigateToParentProperty));
}
}
protected void NavigateToProperty(object o, string? entityName)
protected void NavigateToProperty(object o, string? entityName)
{
var oldSelectedEntity = SelectedEntity;
if (oldSelectedEntity is IAvaloniaObject ao1)
{
ao1.PropertyChanged -= ControlPropertyChanged;
}
else if (oldSelectedEntity is INotifyPropertyChanged inpc1)
switch (oldSelectedEntity)
{
inpc1.PropertyChanged -= ControlPropertyChanged;
case IAvaloniaObject ao1:
ao1.PropertyChanged -= ControlPropertyChanged;
break;
case INotifyPropertyChanged inpc1:
inpc1.PropertyChanged -= ControlPropertyChanged;
break;
}
SelectedEntity = o;
SelectedEntityName = entityName;
SelectedEntityType = o.ToString();
var properties = GetAvaloniaProperties(o)
.Concat(GetClrProperties(o, _showImplementedInterfaces))
.OrderBy(x => x, PropertyComparer.Instance)
.ThenBy(x => x.Name)
.ToArray();
_propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToArray());
_propertyIndex = properties
.GroupBy(x => x.Key)
.ToDictionary(x => x.Key, x => x.ToArray());
TreePage.PropertiesFilter.FilterString = string.Empty;
var view = new DataGridCollectionView(properties);
view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group)));
view.Filter = FilterProperty;
PropertiesView = view;
if (o is IAvaloniaObject ao2)
switch (o)
{
ao2.PropertyChanged += ControlPropertyChanged;
}
else if (o is INotifyPropertyChanged inpc2)
{
inpc2.PropertyChanged += ControlPropertyChanged;
case IAvaloniaObject ao2:
ao2.PropertyChanged += ControlPropertyChanged;
break;
case INotifyPropertyChanged inpc2:
inpc2.PropertyChanged += ControlPropertyChanged;
break;
}
}
@ -498,7 +538,9 @@ namespace Avalonia.Diagnostics.ViewModels
if (SelectedEntity != _avaloniaObject)
{
NavigateToProperty(_avaloniaObject, (_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString());
NavigateToProperty(
_avaloniaObject,
(_avaloniaObject as IControl)?.Name ?? _avaloniaObject.ToString());
}
if (PropertiesView is null)

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

@ -30,7 +30,11 @@
<Grid Grid.Column="0" RowDefinitions="Auto,Auto,*">
<Grid ColumnDefinitions="Auto, *" RowDefinitions="Auto, Auto">
<Button Grid.Column="0" Grid.RowSpan="2" Content="^" Command="{Binding ApplyParentProperty}" />
<Button Grid.Column="0" Grid.RowSpan="2" Content="^"
IsEnabled="{Binding CanNavigateToParentProperty}"
Margin="0 0 4 0"
ToolTip.Tip="Navigate to parent property"
Command="{Binding NavigateToParentProperty}" />
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding SelectedEntityName}" FontWeight="Bold" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding SelectedEntityType}" FontStyle="Italic" />
</Grid>

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

@ -25,7 +25,7 @@ namespace Avalonia.Diagnostics.Views
{
if (sender is DataGrid grid && grid.DataContext is ControlDetailsViewModel controlDetails)
{
controlDetails.ApplySelectedProperty();
controlDetails.NavigateToSelectedProperty();
}
}

Loading…
Cancel
Save