diff --git a/src/Avalonia.Base/Controls/ResourceDictionary.cs b/src/Avalonia.Base/Controls/ResourceDictionary.cs index 77863e5101..e3a8bbbcbc 100644 --- a/src/Avalonia.Base/Controls/ResourceDictionary.cs +++ b/src/Avalonia.Base/Controls/ResourceDictionary.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using Avalonia.Collections; +using Avalonia.Controls.Templates; namespace Avalonia.Controls { @@ -29,7 +30,11 @@ namespace Avalonia.Controls public object? this[object key] { - get => _inner?[key]; + get + { + TryGetValue(key, out var value); + return value; + } set { Inner[key] = value; @@ -119,6 +124,12 @@ namespace Avalonia.Controls Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); } + public void AddDeferred(object key, Func factory) + { + Inner.Add(key, new DeferredItem(factory)); + Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); + } + public void Clear() { if (_inner?.Count > 0) @@ -143,10 +154,8 @@ namespace Avalonia.Controls public bool TryGetResource(object key, out object? value) { - if (_inner is not null && _inner.TryGetValue(key, out value)) - { + if (TryGetValue(key, out value)) return true; - } if (_mergedDictionaries != null) { @@ -165,13 +174,24 @@ namespace Avalonia.Controls public bool TryGetValue(object key, out object? value) { - if (_inner is not null) - return _inner.TryGetValue(key, out value); + if (_inner is not null && _inner.TryGetValue(key, out value)) + { + if (value is DeferredItem deffered) + { + _inner[key] = value = deffered.Factory(null) switch + { + ITemplateResult t => t.Result, + object v => v, + _ => null, + }; + } + return true; + } + value = null; return false; } - void ICollection>.Add(KeyValuePair item) { Add(item.Key, item.Value); @@ -258,5 +278,11 @@ namespace Avalonia.Controls } } } + + private class DeferredItem + { + public DeferredItem(Func factory) => Factory = factory; + public Func Factory { get; } + } } } diff --git a/src/Avalonia.Base/Controls/Templates/ITemplateResult.cs b/src/Avalonia.Base/Controls/Templates/ITemplateResult.cs new file mode 100644 index 0000000000..6bd4d735a7 --- /dev/null +++ b/src/Avalonia.Base/Controls/Templates/ITemplateResult.cs @@ -0,0 +1,8 @@ +namespace Avalonia.Controls.Templates +{ + public interface ITemplateResult + { + public object? Result { get; } + public INameScope NameScope { get; } + } +} diff --git a/src/Avalonia.Controls/Templates/TemplateResult.cs b/src/Avalonia.Base/Controls/Templates/TemplateResult.cs similarity index 80% rename from src/Avalonia.Controls/Templates/TemplateResult.cs rename to src/Avalonia.Base/Controls/Templates/TemplateResult.cs index 770aecc329..0e38c6c0ce 100644 --- a/src/Avalonia.Controls/Templates/TemplateResult.cs +++ b/src/Avalonia.Base/Controls/Templates/TemplateResult.cs @@ -1,9 +1,10 @@ namespace Avalonia.Controls.Templates { - public class TemplateResult + public class TemplateResult : ITemplateResult { public T Result { get; } public INameScope NameScope { get; } + object? ITemplateResult.Result => Result; public TemplateResult(T result, INameScope nameScope) {