Sfoglia il codice sorgente

Fixes defBase behavior when removed/added from collection.

Jumar Macato 6 anni fa
parent
commit
78e6ef6e53

+ 29 - 0
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<DefinitionBase>()
+                            ?? Enumerable.Empty<DefinitionBase>())
+            {
+                nD.Parent = this.Parent;
+                nD.OnEnterParentTree();
+            }
+
+            foreach (var oD in e.OldItems?.Cast<DefinitionBase>()
+                            ?? Enumerable.Empty<DefinitionBase>())
+            {
+                oD.Parent = null;
+                oD.OnExitParentTree();
+            }
+
+            IsDirty = true;
         }
 
         /// <summary>

+ 1 - 1
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"
 

+ 11 - 35
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
 
         /// <summary>
         /// Convenience accessor to ValidDefinitionsUStructure bit flag.
-        /// </summary>
+        /// </summary> 
         internal bool ColumnDefinitionsDirty
         {
-            get { return (!CheckFlagsAnd(Flags.ValidDefinitionsUStructure)); }
-            set { SetFlags(!value, Flags.ValidDefinitionsUStructure); }
+            get => ColumnDefinitions?.IsDirty ?? false;
+            set => ColumnDefinitions.IsDirty = value;
         }
 
         /// <summary>
         /// Convenience accessor to ValidDefinitionsVStructure bit flag.
         /// </summary>
-        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<DefinitionBase>())
-                            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<DefinitionBase>())
-                            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;
             }
 

+ 28 - 0
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<DefinitionBase>()
+                            ?? Enumerable.Empty<DefinitionBase>())
+            {
+                nD.Parent = this.Parent;
+                nD.OnEnterParentTree();
+            }
+
+            foreach (var oD in e.OldItems?.Cast<DefinitionBase>()
+                            ?? Enumerable.Empty<DefinitionBase>())
+            {
+                oD.Parent = null;
+                oD.OnExitParentTree();
+            }
+
+            IsDirty = true;
         }
 
         /// <summary>