From f2416db72dc2dcbb32d893b77a945e2bd13f8f0d Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 14 Sep 2024 15:51:12 -0700 Subject: [PATCH 1/3] Make base project internals visible to DiagnosticsSupport, just in case for now --- src/Avalonia.Base/Avalonia.Base.csproj | 1 + src/Avalonia.Controls/Avalonia.Controls.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 8d691c35868..15f0665fd05 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -59,6 +59,7 @@ + diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 70abf7573df..0021d5bb751 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -20,6 +20,7 @@ + From d76d9a0dfe4cbd22274e2b69fdf68eab8d2022ec Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 14 Sep 2024 15:51:41 -0700 Subject: [PATCH 2/3] Make ValueStoreDiagnostic diagnostic API more usable with wider range of types --- .../Diagnostics/AvaloniaObjectExtensions.cs | 9 ++++ .../Diagnostics/IValueFrameDiagnostic.cs | 4 +- .../Diagnostics/LocalValueFrameDiagnostic.cs | 4 +- .../Diagnostics/StyleValueFrameDiagnostic.cs | 24 +--------- .../Diagnostics/StyledElementExtensions.cs | 11 +---- .../Diagnostics/ValueFrameDiagnostic.cs | 5 +- .../ViewModels/ValueFrameViewModel.cs | 46 +++++++++++++++++-- 7 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/Avalonia.Base/Diagnostics/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/Diagnostics/AvaloniaObjectExtensions.cs index 270cac95f20..6a636b3ae53 100644 --- a/src/Avalonia.Base/Diagnostics/AvaloniaObjectExtensions.cs +++ b/src/Avalonia.Base/Diagnostics/AvaloniaObjectExtensions.cs @@ -18,5 +18,14 @@ public static AvaloniaPropertyValue GetDiagnostic(this AvaloniaObject o, Avaloni { return o.GetDiagnosticInternal(property); } + + /// + /// Gets a value store diagnostics for a . + /// + /// The avalonia object. + public static ValueStoreDiagnostic GetValueStoreDiagnostic(this AvaloniaObject avaloniaObject) + { + return avaloniaObject.GetValueStore().GetStoreDiagnostic(); + } } } diff --git a/src/Avalonia.Base/Diagnostics/IValueFrameDiagnostic.cs b/src/Avalonia.Base/Diagnostics/IValueFrameDiagnostic.cs index 1c1ff4fd2f2..fc23775c977 100644 --- a/src/Avalonia.Base/Diagnostics/IValueFrameDiagnostic.cs +++ b/src/Avalonia.Base/Diagnostics/IValueFrameDiagnostic.cs @@ -19,8 +19,8 @@ public enum FrameType Style, Template } - - string? Description { get; } + + object? Source { get; } FrameType Type { get; } bool IsActive { get; } BindingPriority Priority { get; } diff --git a/src/Avalonia.Base/Diagnostics/LocalValueFrameDiagnostic.cs b/src/Avalonia.Base/Diagnostics/LocalValueFrameDiagnostic.cs index 96d72c1480f..e8d3c3f7a2c 100644 --- a/src/Avalonia.Base/Diagnostics/LocalValueFrameDiagnostic.cs +++ b/src/Avalonia.Base/Diagnostics/LocalValueFrameDiagnostic.cs @@ -9,8 +9,8 @@ public LocalValueFrameDiagnostic(IEnumerable values) { Values = values; } - - public string? Description => null; + + public object? Source => null; public IValueFrameDiagnostic.FrameType Type => IValueFrameDiagnostic.FrameType.Local; public bool IsActive => true; public BindingPriority Priority => BindingPriority.LocalValue; diff --git a/src/Avalonia.Base/Diagnostics/StyleValueFrameDiagnostic.cs b/src/Avalonia.Base/Diagnostics/StyleValueFrameDiagnostic.cs index 871ea7dfc0f..2b0d6c3c644 100644 --- a/src/Avalonia.Base/Diagnostics/StyleValueFrameDiagnostic.cs +++ b/src/Avalonia.Base/Diagnostics/StyleValueFrameDiagnostic.cs @@ -15,12 +15,7 @@ internal StyleValueFrameDiagnostic(StyleInstance styleInstance) _styleInstance = styleInstance; } - public string? Description => _styleInstance.Source switch - { - Style s => GetFullSelector(s), - ControlTheme t => t.TargetType?.Name, - _ => null - }; + public object? Source => _styleInstance.Source; public IValueFrameDiagnostic.FrameType Type => _styleInstance.Source switch { @@ -45,23 +40,6 @@ public IEnumerable Values } } - private string GetFullSelector(Style? style) - { - var selectors = new Stack(); - - while (style is not null) - { - if (style.Selector is not null) - { - selectors.Push(style.Selector.ToString()); - } - - style = style.Parent as Style; - } - - return string.Concat(selectors); - } - [Unstable("Compatibility with 11.x")] public AppliedStyle AsAppliedStyle() => new AppliedStyle(_styleInstance); } diff --git a/src/Avalonia.Base/Diagnostics/StyledElementExtensions.cs b/src/Avalonia.Base/Diagnostics/StyledElementExtensions.cs index b4d52c05483..78ab52a6bc6 100644 --- a/src/Avalonia.Base/Diagnostics/StyledElementExtensions.cs +++ b/src/Avalonia.Base/Diagnostics/StyledElementExtensions.cs @@ -11,16 +11,7 @@ namespace Avalonia.Diagnostics; [PrivateApi] public static class StyledElementExtensions { - /// - /// Gets a style diagnostics for a . - /// - /// The element. - public static ValueStoreDiagnostic GetValueStoreDiagnostic(this StyledElement styledElement) - { - return styledElement.GetValueStore().GetStoreDiagnostic(); - } - - [Obsolete("Use StyledElementExtensions.GetValueStoreDiagnostic instead", true)] + [Obsolete("Use AvaloniaObjectExtensions.GetValueStoreDiagnostic instead", true)] public static StyleDiagnostics GetStyleDiagnostics(this StyledElement styledElement) { var diagnostics = styledElement.GetValueStore().GetStoreDiagnostic(); diff --git a/src/Avalonia.Base/Diagnostics/ValueFrameDiagnostic.cs b/src/Avalonia.Base/Diagnostics/ValueFrameDiagnostic.cs index 9b28cf0cdbd..ee331073ed4 100644 --- a/src/Avalonia.Base/Diagnostics/ValueFrameDiagnostic.cs +++ b/src/Avalonia.Base/Diagnostics/ValueFrameDiagnostic.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Avalonia.Data; using Avalonia.PropertyStore; using Avalonia.Styling; @@ -14,7 +15,7 @@ internal ValueFrameDiagnostic(ValueFrame valueFrame) _valueFrame = valueFrame; } - public string? Description => (_valueFrame.Owner?.Owner as StyledElement)?.StyleKey.Name; + public object? Source => _valueFrame.Owner?.Owner; public IValueFrameDiagnostic.FrameType Type => IValueFrameDiagnostic.FrameType.Template; diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ValueFrameViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ValueFrameViewModel.cs index 924ac287fc3..80d89500b60 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ValueFrameViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ValueFrameViewModel.cs @@ -20,12 +20,13 @@ public ValueFrameViewModel(StyledElement styledElement, IValueFrameDiagnostic va _valueFrame = valueFrame; IsVisible = true; - Description = (_valueFrame.Type, _valueFrame.Description) switch + var source = SourceToString(_valueFrame.Source); + Description = (_valueFrame.Type, source) switch { - (IValueFrameDiagnostic.FrameType.Local, _) => "Local Values " + _valueFrame.Description, - (IValueFrameDiagnostic.FrameType.Template, _) => "Template " + _valueFrame.Description, - (IValueFrameDiagnostic.FrameType.Theme, _) => "Theme " + _valueFrame.Description, - (_, {Length:>0}) => _valueFrame.Description, + (IValueFrameDiagnostic.FrameType.Local, _) => "Local Values " + source, + (IValueFrameDiagnostic.FrameType.Template, _) => "Template " + source, + (IValueFrameDiagnostic.FrameType.Theme, _) => "Theme " + source, + (_, {Length:>0}) => source, _ => _valueFrame.Priority.ToString() }; @@ -113,5 +114,40 @@ private static bool IsBinding(object? value) return false; } + + private string? SourceToString(object? source) + { + if (source is Style style) + { + StyleBase? currentStyle = style; + var selectors = new Stack(); + + while (currentStyle is not null) + { + if (currentStyle is Style { Selector: { } selector }) + { + selectors.Push(selector.ToString()); + } + if (currentStyle is ControlTheme theme) + { + selectors.Push("Theme " + theme.TargetType?.Name); + } + + currentStyle = currentStyle.Parent as StyleBase; + } + + return string.Concat(selectors).Replace("^", ""); + } + else if (source is ControlTheme controlTheme) + { + return controlTheme.TargetType?.Name; + } + else if (source is StyledElement styledElement) + { + return styledElement.StyleKey?.Name; + } + + return null; + } } } From 5876a7735075c5aea4666e028f84c60cbbfa62b2 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 14 Sep 2024 15:53:51 -0700 Subject: [PATCH 3/3] Add MultiBindingExpression internal members for visibilty --- src/Avalonia.Base/Data/Core/MultiBindingExpression.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Avalonia.Base/Data/Core/MultiBindingExpression.cs b/src/Avalonia.Base/Data/Core/MultiBindingExpression.cs index cd012f9b213..4d0a612a7e1 100644 --- a/src/Avalonia.Base/Data/Core/MultiBindingExpression.cs +++ b/src/Avalonia.Base/Data/Core/MultiBindingExpression.cs @@ -49,6 +49,12 @@ public MultiBindingExpression( } public override string Description => "MultiBinding"; + internal UntypedBindingExpressionBase?[] Expressions => _expressions; + internal IMultiValueConverter? Converter => _converter; + internal CultureInfo? ConverterCulture => _converterCulture; + internal object? ConverterParameter => _converterParameter; + internal object? FallbackValue => _fallbackValue; + internal object? TargetNullValue => _targetNullValue; protected override void StartCore() {