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,
IResourceProvider
{
private readonly AvaloniaList<IStyle> _styles = new AvaloniaList<IStyle>();
private readonly AvaloniaList<IStyle> _styles = new();
private IResourceHost? _owner;
private IResourceDictionary? _resources;
private StyleCache? _cache;
@ -62,16 +62,18 @@ namespace Avalonia.Styling
{
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;
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)
{
if (i is IResourceProvider p && p.HasResources)
if (i is IResourceProvider { HasResources: true })
{
return true;
}
@ -190,7 +192,7 @@ namespace Avalonia.Styling
{
owner = owner ?? throw new ArgumentNullException(nameof(owner));
if (Owner != null)
if (Owner is not null)
{
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 (IReadOnlyList<T>)list;
}
else
{
var result = new T[list.Count];
list.CopyTo(result, 0);
return result;
}
return readOnlyList;
}
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)
{
var style = (IStyle)items[i]!;
if (Owner is object && style is IResourceProvider resourceProvider)
if (items[i] is IResourceProvider provider)
{
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)
{
var style = (IStyle)items[i]!;
if (Owner is object && style is IResourceProvider resourceProvider)
if (items[i] is IResourceProvider provider)
{
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)
{
case NotifyCollectionChangedAction.Add:
Add(e.NewItems!);
InternalAdd(e.NewItems!, currentOwner, ref _cache);
break;
case NotifyCollectionChangedAction.Remove:
Remove(e.OldItems!);
InternalRemove(e.OldItems!, currentOwner, ref _cache);
break;
case NotifyCollectionChangedAction.Replace:
Remove(e.OldItems!);
Add(e.NewItems!);
InternalRemove(e.OldItems!, currentOwner, ref _cache);
InternalAdd(e.NewItems!, currentOwner, ref _cache);
break;
case NotifyCollectionChangedAction.Reset:
throw new InvalidOperationException("Reset should not be called on Styles.");
}
CollectionChanged?.Invoke(this, e);

Loading…
Cancel
Save