Browse Source

Add deferred support to ResourceDictionary.

pull/8422/head
Steven Kirk 4 years ago
parent
commit
6bd0d2818c
  1. 40
      src/Avalonia.Base/Controls/ResourceDictionary.cs
  2. 8
      src/Avalonia.Base/Controls/Templates/ITemplateResult.cs
  3. 3
      src/Avalonia.Base/Controls/Templates/TemplateResult.cs

40
src/Avalonia.Base/Controls/ResourceDictionary.cs

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls.Templates;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -29,7 +30,11 @@ namespace Avalonia.Controls
public object? this[object key] public object? this[object key]
{ {
get => _inner?[key]; get
{
TryGetValue(key, out var value);
return value;
}
set set
{ {
Inner[key] = value; Inner[key] = value;
@ -119,6 +124,12 @@ namespace Avalonia.Controls
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
} }
public void AddDeferred(object key, Func<IServiceProvider?, object?> factory)
{
Inner.Add(key, new DeferredItem(factory));
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
}
public void Clear() public void Clear()
{ {
if (_inner?.Count > 0) if (_inner?.Count > 0)
@ -143,10 +154,8 @@ namespace Avalonia.Controls
public bool TryGetResource(object key, out object? value) 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; return true;
}
if (_mergedDictionaries != null) if (_mergedDictionaries != null)
{ {
@ -165,13 +174,24 @@ namespace Avalonia.Controls
public bool TryGetValue(object key, out object? value) public bool TryGetValue(object key, out object? value)
{ {
if (_inner is not null) if (_inner is not null && _inner.TryGetValue(key, out value))
return _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; value = null;
return false; return false;
} }
void ICollection<KeyValuePair<object, object?>>.Add(KeyValuePair<object, object?> item) void ICollection<KeyValuePair<object, object?>>.Add(KeyValuePair<object, object?> item)
{ {
Add(item.Key, item.Value); Add(item.Key, item.Value);
@ -258,5 +278,11 @@ namespace Avalonia.Controls
} }
} }
} }
private class DeferredItem
{
public DeferredItem(Func<IServiceProvider?, object?> factory) => Factory = factory;
public Func<IServiceProvider?, object?> Factory { get; }
}
} }
} }

8
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; }
}
}

3
src/Avalonia.Controls/Templates/TemplateResult.cs → src/Avalonia.Base/Controls/Templates/TemplateResult.cs

@ -1,9 +1,10 @@
namespace Avalonia.Controls.Templates namespace Avalonia.Controls.Templates
{ {
public class TemplateResult<T> public class TemplateResult<T> : ITemplateResult
{ {
public T Result { get; } public T Result { get; }
public INameScope NameScope { get; } public INameScope NameScope { get; }
object? ITemplateResult.Result => Result;
public TemplateResult(T result, INameScope nameScope) public TemplateResult(T result, INameScope nameScope)
{ {
Loading…
Cancel
Save