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