diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs index 804bb09510..6b1934ed06 100644 --- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs +++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs @@ -25,7 +25,6 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport private AutoResetEvent _wakeup = new AutoResetEvent(false); private FrameMessage _lastFrameMessage = null; private FrameMessage _lastSentFrameMessage = null; - private RequestViewportResizeMessage _lastViewportRequest; private Action _onMessage; private Action _onException; @@ -177,6 +176,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport public void Dispose() { + _disposed = true; _pendingSocket?.Dispose(); _simpleServer.Dispose(); } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs index e4c4ca6115..8ce99d5375 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs @@ -19,7 +19,7 @@ namespace Avalonia.Diagnostics.ViewModels Name = property.IsAttached ? $"[{property.OwnerType.Name}.{property.Name}]" : property.Name; - + DeclaringType = property.OwnerType; Update(); } @@ -50,6 +50,8 @@ namespace Avalonia.Diagnostics.ViewModels public override string Group => _group; + public override System.Type? DeclaringType { get; } + // [MemberNotNull(nameof(_type), nameof(_group), nameof(_priority))] public override void Update() { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs index 65626aeea5..0a851f4a19 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs @@ -24,7 +24,7 @@ namespace Avalonia.Diagnostics.ViewModels { Name = property.DeclaringType.Name + '.' + property.Name; } - + DeclaringType = property.DeclaringType; Update(); } @@ -55,6 +55,8 @@ namespace Avalonia.Diagnostics.ViewModels public override bool? IsAttached => default; + public override System.Type? DeclaringType { get; } + // [MemberNotNull(nameof(_type))] public override void Update() { diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs index 3790951b0c..7b32e21fbd 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -17,42 +17,26 @@ namespace Avalonia.Diagnostics.ViewModels internal class ControlDetailsViewModel : ViewModelBase, IDisposable { private readonly IVisual _control; - private readonly IDictionary> _propertyIndex; + private IDictionary> _propertyIndex; private PropertyViewModel? _selectedProperty; + private DataGridCollectionView _propertiesView; private bool _snapshotStyles; private bool _showInactiveStyles; private string? _styleStatus; + private object _selectedEntity; + private readonly Stack<(string Name,object Entry)> _selectedEntitiesStack = new(); + private string _selectedEntityName; + private string _selectedEntityType; public ControlDetailsViewModel(TreePageViewModel treePage, IVisual control) { _control = control; TreePage = treePage; - - var properties = GetAvaloniaProperties(control) - .Concat(GetClrProperties(control)) - .OrderBy(x => x, PropertyComparer.Instance) - .ThenBy(x => x.Name) - .ToList(); - - _propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToList()); - - var view = new DataGridCollectionView(properties); - view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group))); - view.Filter = FilterProperty; - PropertiesView = view; - + Layout = new ControlLayoutViewModel(control); - if (control is INotifyPropertyChanged inpc) - { - inpc.PropertyChanged += ControlPropertyChanged; - } - - if (control is AvaloniaObject ao) - { - ao.PropertyChanged += ControlPropertyChanged; - } + NavigateToProperty(control, (control as IControl)?.Name ?? control.ToString()); AppliedStyles = new ObservableCollection(); PseudoClasses = new ObservableCollection(); @@ -133,12 +117,46 @@ namespace Avalonia.Diagnostics.ViewModels public TreePageViewModel TreePage { get; } - public DataGridCollectionView PropertiesView { get; } + public DataGridCollectionView PropertiesView + { + get => _propertiesView; + private set => RaiseAndSetIfChanged(ref _propertiesView, value); + } public ObservableCollection AppliedStyles { get; } public ObservableCollection PseudoClasses { get; } + public object SelectedEntity + { + get => _selectedEntity; + set + { + RaiseAndSetIfChanged(ref _selectedEntity, value); + + } + } + + public string SelectedEntityName + { + get => _selectedEntityName; + set + { + RaiseAndSetIfChanged(ref _selectedEntityName, value); + + } + } + + public string SelectedEntityType + { + get => _selectedEntityType; + set + { + RaiseAndSetIfChanged(ref _selectedEntityType, value); + + } + } + public PropertyViewModel? SelectedProperty { get => _selectedProperty; @@ -378,5 +396,78 @@ namespace Avalonia.Diagnostics.ViewModels } } } + + public void ApplySelectedProperty() + { + var selectedProperty = SelectedProperty; + var selectedEntity = SelectedEntity; + var selectedEntityName = SelectedEntityName; + if (selectedProperty == null) + return; + + object? property; + if (selectedProperty.Key is AvaloniaProperty avaloniaProperty) + { + property = (_selectedEntity as IControl)?.GetValue(avaloniaProperty); + } + else + { + property = selectedEntity.GetType().GetProperties() + .FirstOrDefault(pi => pi.Name == selectedProperty.Name + && pi.DeclaringType == selectedProperty.DeclaringType + && pi.PropertyType.Name == selectedProperty.Type) + ?.GetValue(selectedEntity); + } + if (property == null) return; + _selectedEntitiesStack.Push((Name:selectedEntityName,Entry:selectedEntity)); + NavigateToProperty(property, selectedProperty.Name); + } + + public void ApplyParentProperty() + { + if (_selectedEntitiesStack.Any()) + { + var property = _selectedEntitiesStack.Pop(); + NavigateToProperty(property.Entry, property.Name); + } + } + + protected void NavigateToProperty(object o, string entityName) + { + var oldSelectedEntity = SelectedEntity; + if (oldSelectedEntity is IAvaloniaObject ao1) + { + ao1.PropertyChanged -= ControlPropertyChanged; + } + else if (oldSelectedEntity is INotifyPropertyChanged inpc1) + { + inpc1.PropertyChanged -= ControlPropertyChanged; + } + + SelectedEntity = o; + SelectedEntityName = entityName; + SelectedEntityType = o.ToString(); + var properties = GetAvaloniaProperties(o) + .Concat(GetClrProperties(o)) + .OrderBy(x => x, PropertyComparer.Instance) + .ThenBy(x => x.Name) + .ToList(); + + _propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToList()); + + var view = new DataGridCollectionView(properties); + view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group))); + view.Filter = FilterProperty; + PropertiesView = view; + + if (o is IAvaloniaObject ao2) + { + ao2.PropertyChanged += ControlPropertyChanged; + } + else if (o is INotifyPropertyChanged inpc2) + { + inpc2.PropertyChanged += ControlPropertyChanged; + } + } } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs index fdbd8c1aa3..173dcd165a 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs @@ -15,6 +15,7 @@ namespace Avalonia.Diagnostics.ViewModels public abstract string Name { get; } public abstract string Group { get; } public abstract string Type { get; } + public abstract Type? DeclaringType { get; } public abstract string Value { get; set; } public abstract string Priority { get; } public abstract bool? IsAttached { get; } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml index 4b37438993..0d81127c21 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml @@ -13,23 +13,30 @@ - + - +