Browse Source

Optimize DefinitionList collection changed handler.

pull/5088/head
Dariusz Komosinski 6 years ago
parent
commit
aefa58bdc4
  1. 60
      src/Avalonia.Controls/DefinitionList.cs

60
src/Avalonia.Controls/DefinitionList.cs

@ -1,8 +1,9 @@
using System; using System.Collections;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
#nullable enable
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
public abstract class DefinitionList<T> : AvaloniaList<T> where T : DefinitionBase public abstract class DefinitionList<T> : AvaloniaList<T> where T : DefinitionBase
@ -14,44 +15,65 @@ namespace Avalonia.Controls
} }
internal bool IsDirty = true; internal bool IsDirty = true;
private Grid _parent; private Grid? _parent;
internal Grid Parent internal Grid? Parent
{ {
get => _parent; get => _parent;
set => SetParent(value); set => SetParent(value);
} }
private void SetParent(Grid value) private void SetParent(Grid? value)
{ {
_parent = value; _parent = value;
foreach (var pair in this.Select((definitions, index) => (definitions, index))) var idx = 0;
foreach (T definition in this)
{ {
pair.definitions.Parent = value; definition.Parent = value;
pair.definitions.Index = pair.index; definition.Index = idx++;
} }
} }
internal void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) internal void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{ {
foreach (var nI in this.Select((d, i) => (d, i))) var idx = 0;
nI.d._parentIndex = nI.i;
foreach (var nD in e.NewItems?.Cast<DefinitionBase>() foreach (T definition in this)
?? Enumerable.Empty<DefinitionBase>())
{ {
nD.Parent = this.Parent; definition.Index = idx++;
nD.OnEnterParentTree();
} }
UpdateDefinitionParent(e.NewItems, false);
UpdateDefinitionParent(e.OldItems, true);
IsDirty = true;
}
foreach (var oD in e.OldItems?.Cast<DefinitionBase>() private void UpdateDefinitionParent(IList? items, bool wasRemoved)
?? Enumerable.Empty<DefinitionBase>()) {
if (items is null)
{ {
oD.OnExitParentTree(); return;
} }
var count = items.Count;
IsDirty = true; for (var i = 0; i < count; i++)
{
var definition = (DefinitionBase) items[i];
if (wasRemoved)
{
definition.OnExitParentTree();
}
else
{
definition.Parent = Parent;
definition.OnEnterParentTree();
}
}
} }
} }
} }

Loading…
Cancel
Save