From 9ff44b7c0a325074f1f9d1b6bdc13cdbab43413e Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Thu, 17 Mar 2022 17:13:35 +0100 Subject: [PATCH 1/2] Add support for showing binding paths in DevTools. --- .../ViewModels/BindingSetterViewModel.cs | 22 +++++++++++++++++++ .../ViewModels/ControlDetailsViewModel.cs | 22 ++++++++++++++++++- .../Diagnostics/ViewModels/SetterViewModel.cs | 2 +- .../Diagnostics/Views/ControlDetailsView.xaml | 20 +++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs new file mode 100644 index 0000000000..143108421e --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs @@ -0,0 +1,22 @@ +using Avalonia.Media; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class BindingSetterViewModel : SetterViewModel + { + public BindingSetterViewModel(AvaloniaProperty property, object? value, string bindingPath, bool isCompiled) : base(property, value) + { + Path = bindingPath; + Tint = isCompiled ? Brushes.DarkGreen : Brushes.CornflowerBlue; + } + + public IBrush Tint { get; } + + public string Path { get; } + + public override void CopyValue() + { + CopyToClipboard(Path); + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs index 8f0a4d07b0..a3a2b0a19c 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -8,6 +8,7 @@ using System.Reflection; using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Metadata; +using Avalonia.Data; using Avalonia.Markup.Xaml.MarkupExtensions; using Avalonia.Styling; using Avalonia.VisualTree; @@ -87,7 +88,16 @@ namespace Avalonia.Diagnostics.ViewModels } else { - setterVm = new SetterViewModel(regularSetter.Property, setterValue); + var bindingInfo = GetBindingInfo(setterValue); + + if (bindingInfo is not null) + { + setterVm = new BindingSetterViewModel(regularSetter.Property, setterValue, bindingInfo.Value.path, bindingInfo.Value.isCompiled); + } + else + { + setterVm = new SetterViewModel(regularSetter.Property, setterValue); + } } setters.Add(setterVm); @@ -117,6 +127,16 @@ namespace Avalonia.Diagnostics.ViewModels return null; } + private (string path, bool isCompiled)? GetBindingInfo(object? value) + { + return value switch + { + Binding binding => (binding.Path, false), + CompiledBindingExtension compiledBinding => (compiledBinding.Path.ToString(), true), + _ => null, + }; + } + public TreePageViewModel TreePage { get; } public DataGridCollectionView? PropertiesView diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/SetterViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/SetterViewModel.cs index 38cbefcb93..559ed49911 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/SetterViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/SetterViewModel.cs @@ -34,7 +34,7 @@ namespace Avalonia.Diagnostics.ViewModels IsVisible = true; } - public void CopyValue() + public virtual void CopyValue() { var textToCopy = Value?.ToString(); diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml index d7acbbd577..ec97b213a9 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml @@ -138,6 +138,26 @@ + + + + + + + + + + + + { + + + } + + + + + From d28b6501f6f26660fae2cbe6f3cfeaf6b182db10 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Thu, 17 Mar 2022 18:07:47 +0100 Subject: [PATCH 2/2] Add support for template bindings. --- .../ViewModels/BindingSetterViewModel.cs | 37 +++++++++++++++++-- .../ViewModels/ControlDetailsViewModel.cs | 21 ++++++----- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs index 143108421e..de3e56e514 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/BindingSetterViewModel.cs @@ -1,13 +1,42 @@ -using Avalonia.Media; +using System; +using Avalonia.Data; +using Avalonia.Markup.Xaml.MarkupExtensions; +using Avalonia.Media; namespace Avalonia.Diagnostics.ViewModels { internal class BindingSetterViewModel : SetterViewModel { - public BindingSetterViewModel(AvaloniaProperty property, object? value, string bindingPath, bool isCompiled) : base(property, value) + public BindingSetterViewModel(AvaloniaProperty property, object? value) : base(property, value) { - Path = bindingPath; - Tint = isCompiled ? Brushes.DarkGreen : Brushes.CornflowerBlue; + switch (value) + { + case Binding binding: + Path = binding.Path; + Tint = Brushes.CornflowerBlue; + + break; + case CompiledBindingExtension binding: + Path = binding.Path.ToString(); + Tint = Brushes.DarkGreen; + + break; + case TemplateBinding binding: + if (binding.Property is AvaloniaProperty templateProperty) + { + Path = $"{templateProperty.OwnerType.Name}.{templateProperty.Name}"; + } + else + { + Path = "Unassigned"; + } + + Tint = Brushes.OrangeRed; + + break; + default: + throw new ArgumentException("Invalid binding type", nameof(value)); + } } public IBrush Tint { get; } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs index a3a2b0a19c..701947d2ab 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -88,11 +88,11 @@ namespace Avalonia.Diagnostics.ViewModels } else { - var bindingInfo = GetBindingInfo(setterValue); + var isBinding = IsBinding(setterValue); - if (bindingInfo is not null) + if (isBinding) { - setterVm = new BindingSetterViewModel(regularSetter.Property, setterValue, bindingInfo.Value.path, bindingInfo.Value.isCompiled); + setterVm = new BindingSetterViewModel(regularSetter.Property, setterValue); } else { @@ -127,14 +127,17 @@ namespace Avalonia.Diagnostics.ViewModels return null; } - private (string path, bool isCompiled)? GetBindingInfo(object? value) + private bool IsBinding(object? value) { - return value switch + switch (value) { - Binding binding => (binding.Path, false), - CompiledBindingExtension compiledBinding => (compiledBinding.Path.ToString(), true), - _ => null, - }; + case Binding: + case CompiledBindingExtension: + case TemplateBinding: + return true; + } + + return false; } public TreePageViewModel TreePage { get; }