Browse Source

Don't make ResourceDictionary inherit...

...from `AvaloniaDictionary`.
pull/8421/head
Steven Kirk 4 years ago
parent
commit
5c6370aa56
  1. 119
      src/Avalonia.Base/Controls/ResourceDictionary.cs

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

@ -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);
}
} }
} }

Loading…
Cancel
Save