From 78e6ef6e53418fc7bc3728cd4b8cc157e12643ef Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Fri, 31 May 2019 22:21:59 +0800 Subject: [PATCH] Fixes defBase behavior when removed/added from collection. --- src/Avalonia.Controls/ColumnDefinitions.cs | 29 ++++++++++++++ src/Avalonia.Controls/DefinitionBase.cs | 2 +- src/Avalonia.Controls/Grid.cs | 46 ++++++---------------- src/Avalonia.Controls/RowDefinitions.cs | 28 +++++++++++++ 4 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/Avalonia.Controls/ColumnDefinitions.cs b/src/Avalonia.Controls/ColumnDefinitions.cs index ecfe6027ac..ae7756e7d1 100644 --- a/src/Avalonia.Controls/ColumnDefinitions.cs +++ b/src/Avalonia.Controls/ColumnDefinitions.cs @@ -1,6 +1,8 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; +using System.Collections.Specialized; using System.Linq; using Avalonia.Collections; @@ -17,6 +19,33 @@ namespace Avalonia.Controls public ColumnDefinitions() { ResetBehavior = ResetBehavior.Remove; + CollectionChanged += OnCollectionChanged; + this.TrackItemPropertyChanged(delegate { IsDirty = true; }); + } + + internal bool IsDirty { get; set; } = true; + internal Grid Parent { get; set; } + + private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + foreach (var nI in this.Select((d, i) => (d, i))) + nI.d._parentIndex = nI.i; + + foreach (var nD in e.NewItems?.Cast() + ?? Enumerable.Empty()) + { + nD.Parent = this.Parent; + nD.OnEnterParentTree(); + } + + foreach (var oD in e.OldItems?.Cast() + ?? Enumerable.Empty()) + { + oD.Parent = null; + oD.OnExitParentTree(); + } + + IsDirty = true; } /// diff --git a/src/Avalonia.Controls/DefinitionBase.cs b/src/Avalonia.Controls/DefinitionBase.cs index e0ed8aa7d7..36dcb714c4 100644 --- a/src/Avalonia.Controls/DefinitionBase.cs +++ b/src/Avalonia.Controls/DefinitionBase.cs @@ -623,7 +623,7 @@ namespace Avalonia.Controls #region Private Fields private readonly bool _isColumnDefinition; // when "true", this is a ColumnDefinition; when "false" this is a RowDefinition (faster than a type check) private Flags _flags; // flags reflecting various aspects of internal state - private int _parentIndex = -1; // this instance's index in parent's children collection + internal int _parentIndex = -1; // this instance's index in parent's children collection private Grid.LayoutTimeSizeType _sizeType; // layout-time user size type. it may differ from _userSizeValueCache.UnitType when calculating "to-content" diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs index 55298abb3a..240ebd4091 100644 --- a/src/Avalonia.Controls/Grid.cs +++ b/src/Avalonia.Controls/Grid.cs @@ -216,7 +216,7 @@ namespace Avalonia.Controls get { if (_data == null) { _data = new ExtendedData(); } - if (_data.ColumnDefinitions == null) { _data.ColumnDefinitions = new ColumnDefinitions(); } + if (_data.ColumnDefinitions == null) { _data.ColumnDefinitions = new ColumnDefinitions() { Parent = this }; } return (_data.ColumnDefinitions); } @@ -224,6 +224,7 @@ namespace Avalonia.Controls { if (_data == null) { _data = new ExtendedData(); } _data.ColumnDefinitions = value; + _data.ColumnDefinitions.Parent = this; } } @@ -235,7 +236,7 @@ namespace Avalonia.Controls get { if (_data == null) { _data = new ExtendedData(); } - if (_data.RowDefinitions == null) { _data.RowDefinitions = new RowDefinitions(); } + if (_data.RowDefinitions == null) { _data.RowDefinitions = new RowDefinitions() { Parent = this }; } return (_data.RowDefinitions); } @@ -243,6 +244,7 @@ namespace Avalonia.Controls { if (_data == null) { _data = new ExtendedData(); } _data.RowDefinitions = value; + _data.RowDefinitions.Parent = this; } } @@ -769,20 +771,20 @@ namespace Avalonia.Controls /// /// Convenience accessor to ValidDefinitionsUStructure bit flag. - /// + /// internal bool ColumnDefinitionsDirty { - get { return (!CheckFlagsAnd(Flags.ValidDefinitionsUStructure)); } - set { SetFlags(!value, Flags.ValidDefinitionsUStructure); } + get => ColumnDefinitions?.IsDirty ?? false; + set => ColumnDefinitions.IsDirty = value; } /// /// Convenience accessor to ValidDefinitionsVStructure bit flag. /// - internal bool RowDefinitionsDirty + internal bool RowDefinitionsDirty { - get { return (!CheckFlagsAnd(Flags.ValidDefinitionsVStructure)); } - set { SetFlags(!value, Flags.ValidDefinitionsVStructure); } + get => RowDefinitions?.IsDirty ?? false; + set => RowDefinitions.IsDirty = value; } //------------------------------------------------------ @@ -944,23 +946,10 @@ namespace Avalonia.Controls } else { - foreach(var definition in extData.DefinitionsU - ?? Enumerable.Empty()) - definition.OnExitParentTree(); - extData.DefinitionsU = extData.ColumnDefinitions; } } - // adds index information. - for(int i = 0; i < extData.DefinitionsU.Count;i++) - { - var definition = extData.DefinitionsU[i]; - definition.Parent = this; - definition.Index = i; - definition.OnEnterParentTree(); - } - ColumnDefinitionsDirty = false; } @@ -997,24 +986,11 @@ namespace Avalonia.Controls extData.DefinitionsV = new DefinitionBase[] { new RowDefinition() }; } else - { - foreach(var definition in extData.DefinitionsV - ?? Enumerable.Empty()) - definition.OnExitParentTree(); - + { extData.DefinitionsV = extData.RowDefinitions; } } - // adds index information. - for(int i = 0; i < extData.DefinitionsV.Count;i++) - { - var definition = extData.DefinitionsV[i]; - definition.Parent = this; - definition.Index = i; - definition.OnEnterParentTree(); - } - RowDefinitionsDirty = false; } diff --git a/src/Avalonia.Controls/RowDefinitions.cs b/src/Avalonia.Controls/RowDefinitions.cs index 1a14cc78f3..c12d284977 100644 --- a/src/Avalonia.Controls/RowDefinitions.cs +++ b/src/Avalonia.Controls/RowDefinitions.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Collections.Specialized; using System.Linq; using Avalonia.Collections; @@ -17,6 +18,33 @@ namespace Avalonia.Controls public RowDefinitions() { ResetBehavior = ResetBehavior.Remove; + CollectionChanged += OnCollectionChanged; + this.TrackItemPropertyChanged(delegate { IsDirty = true; }); + } + + internal bool IsDirty { get; set; } = true; + internal Grid Parent { get; set; } + + private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + foreach (var nI in this.Select((d, i) => (d, i))) + nI.d._parentIndex = nI.i; + + foreach (var nD in e.NewItems?.Cast() + ?? Enumerable.Empty()) + { + nD.Parent = this.Parent; + nD.OnEnterParentTree(); + } + + foreach (var oD in e.OldItems?.Cast() + ?? Enumerable.Empty()) + { + oD.Parent = null; + oD.OnExitParentTree(); + } + + IsDirty = true; } ///