From aefa58bdc4b1dabf5f8bb8832867b01ca5e39d26 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Sun, 22 Nov 2020 22:43:25 +0100 Subject: [PATCH] Optimize DefinitionList collection changed handler. --- src/Avalonia.Controls/DefinitionList.cs | 60 +++++++++++++++++-------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/src/Avalonia.Controls/DefinitionList.cs b/src/Avalonia.Controls/DefinitionList.cs index bb815171c0..ad0e2513c4 100644 --- a/src/Avalonia.Controls/DefinitionList.cs +++ b/src/Avalonia.Controls/DefinitionList.cs @@ -1,8 +1,9 @@ -using System; +using System.Collections; using System.Collections.Specialized; -using System.Linq; using Avalonia.Collections; +#nullable enable + namespace Avalonia.Controls { public abstract class DefinitionList : AvaloniaList where T : DefinitionBase @@ -14,44 +15,65 @@ namespace Avalonia.Controls } internal bool IsDirty = true; - private Grid _parent; + private Grid? _parent; - internal Grid Parent + internal Grid? Parent { get => _parent; set => SetParent(value); } - private void SetParent(Grid value) + private void SetParent(Grid? 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; - pair.definitions.Index = pair.index; + definition.Parent = value; + definition.Index = idx++; } } internal void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - foreach (var nI in this.Select((d, i) => (d, i))) - nI.d._parentIndex = nI.i; + var idx = 0; - foreach (var nD in e.NewItems?.Cast() - ?? Enumerable.Empty()) + foreach (T definition in this) { - nD.Parent = this.Parent; - nD.OnEnterParentTree(); + definition.Index = idx++; } + + UpdateDefinitionParent(e.NewItems, false); + UpdateDefinitionParent(e.OldItems, true); + + IsDirty = true; + } - foreach (var oD in e.OldItems?.Cast() - ?? Enumerable.Empty()) + private void UpdateDefinitionParent(IList? items, bool wasRemoved) + { + 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(); + } + } } } -} \ No newline at end of file +}