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