|
|
@ -1,38 +1,45 @@ |
|
|
using System; |
|
|
using System; |
|
|
|
|
|
using System.Collections; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Specialized; |
|
|
using System.Linq; |
|
|
using Avalonia.Collections; |
|
|
using Avalonia.Collections; |
|
|
using Avalonia.Metadata; |
|
|
|
|
|
|
|
|
|
|
|
#nullable enable |
|
|
|
|
|
|
|
|
|
|
|
namespace Avalonia.Controls |
|
|
namespace Avalonia.Controls |
|
|
{ |
|
|
{ |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// An indexed dictionary of resources.
|
|
|
/// An indexed dictionary of resources.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public class ResourceDictionary : AvaloniaDictionary<object, object?>, IResourceDictionary |
|
|
public class ResourceDictionary : IResourceDictionary |
|
|
{ |
|
|
{ |
|
|
|
|
|
private Dictionary<object, object?>? _inner; |
|
|
private IResourceHost? _owner; |
|
|
private IResourceHost? _owner; |
|
|
private AvaloniaList<IResourceProvider>? _mergedDictionaries; |
|
|
private AvaloniaList<IResourceProvider>? _mergedDictionaries; |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="ResourceDictionary"/> class.
|
|
|
/// Initializes a new instance of the <see cref="ResourceDictionary"/> class.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public ResourceDictionary() |
|
|
public ResourceDictionary() { } |
|
|
{ |
|
|
|
|
|
CollectionChanged += OnCollectionChanged; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="ResourceDictionary"/> class.
|
|
|
/// Initializes a new instance of the <see cref="ResourceDictionary"/> class.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public ResourceDictionary(IResourceHost owner) |
|
|
public ResourceDictionary(IResourceHost owner) => Owner = owner; |
|
|
: this() |
|
|
|
|
|
|
|
|
public int Count => _inner?.Count ?? 0; |
|
|
|
|
|
|
|
|
|
|
|
public object? this[object key] |
|
|
{ |
|
|
{ |
|
|
Owner = owner; |
|
|
get => _inner?[key]; |
|
|
|
|
|
set |
|
|
|
|
|
{ |
|
|
|
|
|
Inner[key] = value; |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ICollection<object> Keys => (ICollection<object>?)_inner?.Keys ?? Array.Empty<object>(); |
|
|
|
|
|
public ICollection<object?> Values => (ICollection<object?>?)_inner?.Values ?? Array.Empty<object?>(); |
|
|
|
|
|
|
|
|
public IResourceHost? Owner |
|
|
public IResourceHost? Owner |
|
|
{ |
|
|
{ |
|
|
get => _owner; |
|
|
get => _owner; |
|
|
@ -80,7 +87,7 @@ namespace Avalonia.Controls |
|
|
{ |
|
|
{ |
|
|
get |
|
|
get |
|
|
{ |
|
|
{ |
|
|
if (Count > 0) |
|
|
if (_inner?.Count > 0) |
|
|
{ |
|
|
{ |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
@ -100,11 +107,43 @@ namespace Avalonia.Controls |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ICollection<KeyValuePair<object, object?>>.IsReadOnly => false; |
|
|
|
|
|
|
|
|
|
|
|
private Dictionary<object, object?> Inner => _inner ??= new(); |
|
|
|
|
|
|
|
|
public event EventHandler? OwnerChanged; |
|
|
public event EventHandler? OwnerChanged; |
|
|
|
|
|
|
|
|
|
|
|
public void Add(object key, object? value) |
|
|
|
|
|
{ |
|
|
|
|
|
Inner.Add(key, value); |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Clear() |
|
|
|
|
|
{ |
|
|
|
|
|
if (_inner?.Count > 0) |
|
|
|
|
|
{ |
|
|
|
|
|
_inner.Clear(); |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool ContainsKey(object key) => _inner?.ContainsKey(key) ?? false; |
|
|
|
|
|
|
|
|
|
|
|
public bool Remove(object key) |
|
|
|
|
|
{ |
|
|
|
|
|
if (_inner?.Remove(key) == true) |
|
|
|
|
|
{ |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public bool TryGetResource(object key, out object? value) |
|
|
public bool TryGetResource(object key, out object? value) |
|
|
{ |
|
|
{ |
|
|
if (TryGetValue(key, out value)) |
|
|
if (_inner is not null && _inner.TryGetValue(key, out value)) |
|
|
{ |
|
|
{ |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
@ -120,9 +159,52 @@ namespace Avalonia.Controls |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
value = null; |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool TryGetValue(object key, out object? value) |
|
|
|
|
|
{ |
|
|
|
|
|
if (_inner is not null) |
|
|
|
|
|
return _inner.TryGetValue(key, out value); |
|
|
|
|
|
value = null; |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ICollection<KeyValuePair<object, object?>>.Add(KeyValuePair<object, object?> item) |
|
|
|
|
|
{ |
|
|
|
|
|
Add(item.Key, item.Value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ICollection<KeyValuePair<object, object?>>.Contains(KeyValuePair<object, object?> item) |
|
|
|
|
|
{ |
|
|
|
|
|
return (_inner as ICollection<KeyValuePair<object, object?>>)?.Contains(item) ?? false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ICollection<KeyValuePair<object, object?>>.CopyTo(KeyValuePair<object, object?>[] array, int arrayIndex) |
|
|
|
|
|
{ |
|
|
|
|
|
(_inner as ICollection<KeyValuePair<object, object?>>)?.CopyTo(array, arrayIndex); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ICollection<KeyValuePair<object, object?>>.Remove(KeyValuePair<object, object?> item) |
|
|
|
|
|
{ |
|
|
|
|
|
if ((_inner as ICollection<KeyValuePair<object, object?>>)?.Remove(item) == true) |
|
|
|
|
|
{ |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public IEnumerator<KeyValuePair<object, object?>> GetEnumerator() |
|
|
|
|
|
{ |
|
|
|
|
|
return _inner?.GetEnumerator() ?? Enumerable.Empty<KeyValuePair<object, object?>>().GetEnumerator(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
|
|
|
|
|
|
|
|
void IResourceProvider.AddOwner(IResourceHost owner) |
|
|
void IResourceProvider.AddOwner(IResourceHost owner) |
|
|
{ |
|
|
{ |
|
|
owner = owner ?? throw new ArgumentNullException(nameof(owner)); |
|
|
owner = owner ?? throw new ArgumentNullException(nameof(owner)); |
|
|
@ -134,7 +216,7 @@ namespace Avalonia.Controls |
|
|
|
|
|
|
|
|
Owner = owner; |
|
|
Owner = owner; |
|
|
|
|
|
|
|
|
var hasResources = Count > 0; |
|
|
var hasResources = _inner?.Count > 0; |
|
|
|
|
|
|
|
|
if (_mergedDictionaries is object) |
|
|
if (_mergedDictionaries is object) |
|
|
{ |
|
|
{ |
|
|
@ -159,7 +241,7 @@ namespace Avalonia.Controls |
|
|
{ |
|
|
{ |
|
|
Owner = null; |
|
|
Owner = null; |
|
|
|
|
|
|
|
|
var hasResources = Count > 0; |
|
|
var hasResources = _inner?.Count > 0; |
|
|
|
|
|
|
|
|
if (_mergedDictionaries is object) |
|
|
if (_mergedDictionaries is object) |
|
|
{ |
|
|
{ |
|
|
@ -176,10 +258,5 @@ namespace Avalonia.Controls |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) |
|
|
|
|
|
{ |
|
|
|
|
|
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|