diff --git a/api/Avalonia.Themes.Fluent.nupkg.xml b/api/Avalonia.Themes.Fluent.nupkg.xml
new file mode 100644
index 0000000000..717b64f81e
--- /dev/null
+++ b/api/Avalonia.Themes.Fluent.nupkg.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ CP0007
+ T:Avalonia.Themes.Fluent.ColorPaletteResources
+ baseline/netstandard2.0/Avalonia.Themes.Fluent.dll
+ target/netstandard2.0/Avalonia.Themes.Fluent.dll
+
+
+ CP0008
+ T:Avalonia.Themes.Fluent.ColorPaletteResources
+ baseline/netstandard2.0/Avalonia.Themes.Fluent.dll
+ target/netstandard2.0/Avalonia.Themes.Fluent.dll
+
+
\ No newline at end of file
diff --git a/src/Avalonia.Base/Controls/ResourceProvider.cs b/src/Avalonia.Base/Controls/ResourceProvider.cs
index f10a816845..0760191d1e 100644
--- a/src/Avalonia.Base/Controls/ResourceProvider.cs
+++ b/src/Avalonia.Base/Controls/ResourceProvider.cs
@@ -7,7 +7,7 @@ namespace Avalonia.Controls;
/// Base implementation for IResourceProvider interface.
/// Includes Owner property management.
///
-public abstract class ResourceProvider : IResourceProvider
+public abstract class ResourceProvider : AvaloniaObject, IResourceProvider
{
private IResourceHost? _owner;
diff --git a/src/Avalonia.Themes.Fluent/ColorPaletteResources.cs b/src/Avalonia.Themes.Fluent/ColorPaletteResources.cs
index ce52f51752..b5b7c80514 100644
--- a/src/Avalonia.Themes.Fluent/ColorPaletteResources.cs
+++ b/src/Avalonia.Themes.Fluent/ColorPaletteResources.cs
@@ -14,13 +14,13 @@ namespace Avalonia.Themes.Fluent;
///
/// This class can only be used in .
///
-public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
+public partial class ColorPaletteResources : ResourceProvider
{
private readonly Dictionary _colors = new(StringComparer.InvariantCulture);
- public bool HasResources => _hasAccentColor || _colors.Count > 0;
+ public override bool HasResources => _hasAccentColor || _colors.Count > 0;
- public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
+ public override bool TryGetResource(object key, ThemeVariant? theme, out object? value)
{
if (key is string strKey)
{
@@ -86,7 +86,7 @@ public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
return default;
}
-
+
private void SetColor(string key, Color value)
{
if (value == default)
@@ -113,6 +113,7 @@ public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
_accentColorLight1, _accentColorLight2, _accentColorLight3) =
SystemAccentColors.CalculateAccentShades(_accentColor);
}
+ RaiseResourcesChanged();
}
}
}
diff --git a/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs b/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs
index 6eb465d399..828cb2e899 100644
--- a/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs
+++ b/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs
@@ -1,20 +1,26 @@
using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Styling;
namespace Avalonia.Themes.Fluent;
-internal class ColorPaletteResourcesCollection : AvaloniaDictionary, IResourceProvider
+internal sealed class ColorPaletteResourcesCollection : ResourceProvider, IDictionary
{
- public ColorPaletteResourcesCollection() : base(2)
+ private readonly AvaloniaDictionary _inner;
+
+ public ColorPaletteResourcesCollection()
{
- this.ForEachItem(
+ _inner = new AvaloniaDictionary(2);
+ _inner.ForEachItem(
(key, x) =>
{
if (Owner is not null)
{
- x.PropertyChanged += Palette_PropertyChanged;
+ ((IResourceProvider)x).AddOwner(Owner);
}
if (key != ThemeVariant.Dark && key != ThemeVariant.Light)
@@ -27,21 +33,21 @@ internal class ColorPaletteResourcesCollection : AvaloniaDictionary throw new NotSupportedException("Dictionary reset not supported"));
}
- public bool HasResources => Count > 0;
- public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
+ public override bool HasResources => _inner.Count > 0;
+ public override bool TryGetResource(object key, ThemeVariant? theme, out object? value)
{
if (theme == null || theme == ThemeVariant.Default)
{
theme = ThemeVariant.Light;
}
- if (base.TryGetValue(theme, out var themePaletteResources)
+ if (_inner.TryGetValue(theme, out var themePaletteResources)
&& themePaletteResources.TryGetResource(key, theme, out value))
{
return true;
@@ -51,25 +57,94 @@ internal class ColorPaletteResourcesCollection : AvaloniaDictionary> IEnumerable>.GetEnumerator()
+ {
+ return _inner.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_inner).GetEnumerator();
+ }
+
+ void ICollection>.Add(KeyValuePair item)
+ {
+ ((ICollection>)_inner).Add(item);
+ }
+
+ void ICollection>.Clear()
+ {
+ _inner.Clear();
+ }
+
+ bool ICollection>.Contains(KeyValuePair item)
+ {
+ return ((ICollection>)_inner).Contains(item);
+ }
+
+ void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex)
+ {
+ _inner.CopyTo(array, arrayIndex);
+ }
+
+ bool ICollection>.Remove(KeyValuePair item)
+ {
+ return ((ICollection>)_inner).Remove(item);
+ }
+
+ int ICollection>.Count => _inner.Count;
+
+ bool ICollection>.IsReadOnly => _inner.IsReadOnly;
+
+ void IDictionary.Add(ThemeVariant key, ColorPaletteResources value)
+ {
+ _inner.Add(key, value);
+ }
+
+ bool IDictionary.ContainsKey(ThemeVariant key)
+ {
+ return _inner.ContainsKey(key);
+ }
+
+ bool IDictionary.Remove(ThemeVariant key)
+ {
+ return _inner.Remove(key);
+ }
+
+ bool IDictionary.TryGetValue(ThemeVariant key,
+#if NET6_0_OR_GREATER
+ [MaybeNullWhen(false)]
+#endif
+ out ColorPaletteResources value)
+ {
+ return _inner.TryGetValue(key, out value);
+ }
+
+ ColorPaletteResources IDictionary.this[ThemeVariant key]
+ {
+ get => _inner[key];
+ set => _inner[key] = value;
+ }
+
+ ICollection IDictionary.Keys => _inner.Keys;
+
+ ICollection IDictionary.Values => _inner.Values;
}
diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs b/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs
index 378041356a..53cd36215c 100644
--- a/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs
+++ b/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs
@@ -54,7 +54,7 @@ namespace Avalonia.Themes.Fluent
get => _densityStyle;
set => SetAndRaise(DensityStyleProperty, ref _densityStyle, value);
}
-
+
public IDictionary Palettes { get; }
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs
index 05b77b5325..1106e7bb99 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs
@@ -991,18 +991,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
}
}
- public class TrackingResourceProvider : IResourceProvider
+ public class TrackingResourceProvider : ResourceProvider
{
- public IResourceHost Owner { get; private set; }
- public bool HasResources => true;
+ public override bool HasResources => true;
public List