Browse Source

Merge pull request #8328 from Maruhl/master

Avalonia.Base - Styles improvements
pull/8373/head
Max Katz 4 years ago
committed by GitHub
parent
commit
59d30b6d62
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 95
      src/Avalonia.Base/Styling/Styles.cs

95
src/Avalonia.Base/Styling/Styles.cs

@ -17,7 +17,7 @@ namespace Avalonia.Styling
IStyle, IStyle,
IResourceProvider IResourceProvider
{ {
private readonly AvaloniaList<IStyle> _styles = new AvaloniaList<IStyle>(); private readonly AvaloniaList<IStyle> _styles = new();
private IResourceHost? _owner; private IResourceHost? _owner;
private IResourceDictionary? _resources; private IResourceDictionary? _resources;
private StyleCache? _cache; private StyleCache? _cache;
@ -62,16 +62,18 @@ namespace Avalonia.Styling
{ {
value = value ?? throw new ArgumentNullException(nameof(Resources)); value = value ?? throw new ArgumentNullException(nameof(Resources));
if (Owner is object) var currentOwner = Owner;
if (currentOwner is not null)
{ {
_resources?.RemoveOwner(Owner); _resources?.RemoveOwner(currentOwner);
} }
_resources = value; _resources = value;
if (Owner is object) if (currentOwner is not null)
{ {
_resources.AddOwner(Owner); _resources.AddOwner(currentOwner);
} }
} }
} }
@ -89,7 +91,7 @@ namespace Avalonia.Styling
foreach (var i in this) foreach (var i in this)
{ {
if (i is IResourceProvider p && p.HasResources) if (i is IResourceProvider { HasResources: true })
{ {
return true; return true;
} }
@ -190,7 +192,7 @@ namespace Avalonia.Styling
{ {
owner = owner ?? throw new ArgumentNullException(nameof(owner)); owner = owner ?? throw new ArgumentNullException(nameof(owner));
if (Owner != null) if (Owner is not null)
{ {
throw new InvalidOperationException("The Styles already has a owner."); throw new InvalidOperationException("The Styles already has a owner.");
} }
@ -227,70 +229,81 @@ namespace Avalonia.Styling
} }
} }
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) private static IReadOnlyList<T> ToReadOnlyList<T>(ICollection list)
{ {
static IReadOnlyList<T> ToReadOnlyList<T>(IList list) if (list is IReadOnlyList<T> readOnlyList)
{ {
if (list is IReadOnlyList<T>) return readOnlyList;
{
return (IReadOnlyList<T>)list;
}
else
{
var result = new T[list.Count];
list.CopyTo(result, 0);
return result;
}
} }
void Add(IList items) var result = new T[list.Count];
list.CopyTo(result, 0);
return result;
}
private static void InternalAdd(IList items, IResourceHost? owner, ref StyleCache? cache)
{
if (owner is not null)
{ {
for (var i = 0; i < items.Count; ++i) for (var i = 0; i < items.Count; ++i)
{ {
var style = (IStyle)items[i]!; if (items[i] is IResourceProvider provider)
if (Owner is object && style is IResourceProvider resourceProvider)
{ {
resourceProvider.AddOwner(Owner); provider.AddOwner(owner);
} }
_cache = null;
} }
(Owner as IStyleHost)?.StylesAdded(ToReadOnlyList<IStyle>(items)); (owner as IStyleHost)?.StylesAdded(ToReadOnlyList<IStyle>(items));
}
if (items.Count > 0)
{
cache = null;
} }
}
void Remove(IList items) private static void InternalRemove(IList items, IResourceHost? owner, ref StyleCache? cache)
{
if (owner is not null)
{ {
for (var i = 0; i < items.Count; ++i) for (var i = 0; i < items.Count; ++i)
{ {
var style = (IStyle)items[i]!; if (items[i] is IResourceProvider provider)
if (Owner is object && style is IResourceProvider resourceProvider)
{ {
resourceProvider.RemoveOwner(Owner); provider.RemoveOwner(owner);
} }
_cache = null;
} }
(Owner as IStyleHost)?.StylesRemoved(ToReadOnlyList<IStyle>(items)); (owner as IStyleHost)?.StylesRemoved(ToReadOnlyList<IStyle>(items));
}
if (items.Count > 0)
{
cache = null;
}
}
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Reset)
{
throw new InvalidOperationException("Reset should not be called on Styles.");
} }
var currentOwner = Owner;
switch (e.Action) switch (e.Action)
{ {
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
Add(e.NewItems!); InternalAdd(e.NewItems!, currentOwner, ref _cache);
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
Remove(e.OldItems!); InternalRemove(e.OldItems!, currentOwner, ref _cache);
break; break;
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
Remove(e.OldItems!); InternalRemove(e.OldItems!, currentOwner, ref _cache);
Add(e.NewItems!); InternalAdd(e.NewItems!, currentOwner, ref _cache);
break; break;
case NotifyCollectionChangedAction.Reset:
throw new InvalidOperationException("Reset should not be called on Styles.");
} }
CollectionChanged?.Invoke(this, e); CollectionChanged?.Invoke(this, e);

Loading…
Cancel
Save