Browse Source

grow datagrid height if there's available space (#16527)

Co-authored-by: Max Katz <[email protected]>
Emmanuel Hansen 1 year ago
parent
commit
f989fec158

+ 7 - 15
src/Avalonia.Controls.DataGrid/DataGrid.cs

@@ -1539,14 +1539,11 @@ namespace Avalonia.Controls
             set;
         }
 
-        // Height currently available for cells this value is smaller.  This height is reduced by the existence of ColumnHeaders
-        // or a horizontal scrollbar.  Layout is asynchronous so changes to the ColumnHeaders or the horizontal scrollbar are
-        // not reflected immediately.
-        internal double CellsHeight
+        internal double CellsEstimatedHeight
         {
             get
             {
-                return RowsPresenterEstimatedAvailableHeight ?? 0;
+                return RowsPresenterAvailableSize?.Height ?? 0;
             }
         }
 
@@ -1832,11 +1829,6 @@ namespace Avalonia.Controls
                 _rowsPresenterAvailableSize = value;
             }
         }
-        internal double? RowsPresenterEstimatedAvailableHeight
-        {
-            get;
-            set;
-        }
 
         internal double[] RowGroupSublevelIndents
         {
@@ -2364,7 +2356,7 @@ namespace Avalonia.Controls
                     }
                     else
                     {
-                        double maximum = EdgedRowsHeightCalculated - CellsHeight;
+                        double maximum = EdgedRowsHeightCalculated - CellsEstimatedHeight;
                         scrollHeight = Math.Min(Math.Max(0, maximum - _verticalOffset), -delta.Y);
                     }
                 }
@@ -3186,7 +3178,7 @@ namespace Avalonia.Controls
         {
             if (_vScrollBar != null && _vScrollBar.IsVisible)
             {
-                double cellsHeight = CellsHeight;
+                double cellsHeight = CellsEstimatedHeight;
                 double edgedRowsHeightCalculated = EdgedRowsHeightCalculated;
                 UpdateVerticalScrollBar(
                     needVertScrollbar: edgedRowsHeightCalculated > cellsHeight,
@@ -3320,7 +3312,7 @@ namespace Avalonia.Controls
                 }
                 if (updated)
                 {
-                    UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsHeight);
+                    UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsEstimatedHeight);
                     InvalidateRowsMeasure(invalidateIndividualElements: false);
                 }
             }
@@ -3554,7 +3546,7 @@ namespace Avalonia.Controls
             bool isVerticalScrollBarOverCells = IsVerticalScrollBarOverCells;
 
             double cellsWidth = CellsWidth;
-            double cellsHeight = CellsHeight;
+            double cellsHeight = CellsEstimatedHeight;
 
             bool allowHorizScrollbar = false;
             bool forceHorizScrollbar = false;
@@ -3611,7 +3603,7 @@ namespace Avalonia.Controls
             double totalVisibleWidth = ColumnsInternal.VisibleEdgedColumnsWidth;
             double totalVisibleFrozenWidth = ColumnsInternal.GetVisibleFrozenEdgedColumnsWidth();
 
-            UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsHeight);
+            UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsEstimatedHeight);
             double totalVisibleHeight = EdgedRowsHeightCalculated;
 
             if (!forceHorizScrollbar && !forceVertScrollbar)

+ 17 - 17
src/Avalonia.Controls.DataGrid/DataGridRows.cs

@@ -425,7 +425,7 @@ namespace Avalonia.Controls
                 {
                     row.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                 }
-                UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsHeight);
+                UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsEstimatedHeight);
             }
 
             if (DisplayData.FirstScrollingSlot < slot && (DisplayData.LastScrollingSlot > slot || DisplayData.LastScrollingSlot == -1))
@@ -462,7 +462,7 @@ namespace Avalonia.Controls
                     ResetDisplayedRows();
                 }
                 NegVerticalOffset = 0;
-                UpdateDisplayedRows(slot, CellsHeight);
+                UpdateDisplayedRows(slot, CellsEstimatedHeight);
             }
             else if (DisplayData.LastScrollingSlot <= slot)
             {
@@ -502,11 +502,11 @@ namespace Avalonia.Controls
                 {
                     ResetDisplayedRows();
                 }
-                if (MathUtilities.GreaterThanOrClose(GetExactSlotElementHeight(slot), CellsHeight))
+                if (MathUtilities.GreaterThanOrClose(GetExactSlotElementHeight(slot), CellsEstimatedHeight))
                 {
                     // The entire row won't fit in the DataGrid so we start showing it from the top
                     NegVerticalOffset = 0;
-                    UpdateDisplayedRows(slot, CellsHeight);
+                    UpdateDisplayedRows(slot, CellsEstimatedHeight);
                 }
                 else
                 {
@@ -972,7 +972,7 @@ namespace Avalonia.Controls
 
             if (isDisplayed)
             {
-                double availableHeight = CellsHeight - heightAboveStartSlot;
+                double availableHeight = CellsEstimatedHeight - heightAboveStartSlot;
                 // Actually expand the displayed slots up to what we can display
                 for (int i = startSlot; (i <= endSlot) && (currentHeightChange < availableHeight); i++)
                 {
@@ -1645,7 +1645,7 @@ namespace Avalonia.Controls
             }
 
             DisplayData.ClearElements(recycle: true);
-            AvailableSlotElementRoom = CellsHeight;
+            AvailableSlotElementRoom = CellsEstimatedHeight;
         }
 
         /// <summary>
@@ -1662,7 +1662,7 @@ namespace Avalonia.Controls
                 return true;
             }
             else if (DisplayData.FirstScrollingSlot == -1 &&
-                     CellsHeight > 0 &&
+                     CellsEstimatedHeight > 0 &&
                      CellsWidth > 0)
             {
                 return true;
@@ -1716,7 +1716,7 @@ namespace Avalonia.Controls
                             // Figure out what row we've scrolled down to and update the value for NegVerticalOffset
                             NegVerticalOffset = 0;
                             //
-                            if (height > 2 * CellsHeight &&
+                            if (height > 2 * CellsEstimatedHeight &&
                                 (RowDetailsVisibilityMode != DataGridRowDetailsVisibilityMode.VisibleWhenSelected || RowDetailsTemplate == null))
                             {
                                 // Very large scroll occurred. Instead of determining the exact number of scrolled off rows,
@@ -1778,7 +1778,7 @@ namespace Avalonia.Controls
                         NegVerticalOffset = 0;
                         //
 
-                        if (height < -2 * CellsHeight &&
+                        if (height < -2 * CellsEstimatedHeight &&
                             (RowDetailsVisibilityMode != DataGridRowDetailsVisibilityMode.VisibleWhenSelected || RowDetailsTemplate == null))
                         {
                             // Very large scroll occurred. Instead of determining the exact number of scrolled off rows,
@@ -1838,7 +1838,7 @@ namespace Avalonia.Controls
                         // strategy. For most data, this should be unnoticeable.
                         ResetDisplayedRows();
                         NegVerticalOffset = 0;
-                        UpdateDisplayedRows(0, CellsHeight);
+                        UpdateDisplayedRows(0, CellsEstimatedHeight);
                         newFirstScrollingSlot = 0;
                     }
                 }
@@ -1857,7 +1857,7 @@ namespace Avalonia.Controls
                     NegVerticalOffset = 0;
                 }
 
-                UpdateDisplayedRows(newFirstScrollingSlot, CellsHeight);
+                UpdateDisplayedRows(newFirstScrollingSlot, CellsEstimatedHeight);
 
                 double firstElementHeight = GetExactSlotElementHeight(DisplayData.FirstScrollingSlot);
                 if (MathUtilities.GreaterThan(NegVerticalOffset, firstElementHeight))
@@ -1883,7 +1883,7 @@ namespace Avalonia.Controls
                     // We could be smarter about this, but it's not common so we wouldn't gain much from optimizing here
                     if (firstElementSlot != DisplayData.FirstScrollingSlot)
                     {
-                        UpdateDisplayedRows(firstElementSlot, CellsHeight);
+                        UpdateDisplayedRows(firstElementSlot, CellsEstimatedHeight);
                     }
                 }
 
@@ -2011,7 +2011,7 @@ namespace Avalonia.Controls
             DisplayData.ClearElements(recycle);
 
             // Update the AvailableRowRoom since we're displaying 0 rows now
-            AvailableSlotElementRoom = CellsHeight;
+            AvailableSlotElementRoom = CellsEstimatedHeight;
             VisibleSlotCount = 0;
         }
 
@@ -2122,7 +2122,7 @@ namespace Avalonia.Controls
 
             int lastDisplayedScrollingRow = newLastDisplayedScrollingRow;
             int firstDisplayedScrollingRow = -1;
-            double displayHeight = CellsHeight;
+            double displayHeight = CellsEstimatedHeight;
             double deltaY = 0;
             int visibleScrollingRows = 0;
 
@@ -2633,7 +2633,7 @@ namespace Avalonia.Controls
                 }
                 if (isDisplayed)
                 {
-                    UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsHeight);
+                    UpdateDisplayedRows(DisplayData.FirstScrollingSlot, CellsEstimatedHeight);
                 }
             }
             else
@@ -2692,7 +2692,7 @@ namespace Avalonia.Controls
                         }
                         else
                         {
-                            UpdateDisplayedRows(newFirstScrollingSlot, CellsHeight);
+                            UpdateDisplayedRows(newFirstScrollingSlot, CellsEstimatedHeight);
                         }
                     }
                 }
@@ -2736,7 +2736,7 @@ namespace Avalonia.Controls
                             NegVerticalOffset = 0;
                             SetVerticalOffset(0);
                             int firstDisplayedRow = GetNextVisibleSlot(-1);
-                            UpdateDisplayedRows(firstDisplayedRow, CellsHeight);
+                            UpdateDisplayedRows(firstDisplayedRow, CellsEstimatedHeight);
                         }
                     }
                 }

+ 0 - 20
src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs

@@ -32,20 +32,6 @@ namespace Avalonia.Controls.Primitives
             set;
         }
 
-        private double _measureHeightOffset = 0;
-
-        private double CalculateEstimatedAvailableHeight(Size availableSize)
-        {
-            if (!Double.IsPositiveInfinity(availableSize.Height))
-            {
-                return availableSize.Height + _measureHeightOffset;
-            }
-            else
-            {
-                return availableSize.Height;
-            }
-        }
-
         event EventHandler<ChildIndexChangedEventArgs> IChildIndexProvider.ChildIndexChanged
         {
             add => _childIndexChanged += value;
@@ -88,11 +74,6 @@ namespace Avalonia.Controls.Primitives
             if (OwningGrid.RowsPresenterAvailableSize.HasValue)
             {
                 var availableHeight = OwningGrid.RowsPresenterAvailableSize.Value.Height;
-                if (!Double.IsPositiveInfinity(availableHeight))
-                {
-                    _measureHeightOffset = finalSize.Height - availableHeight;
-                    OwningGrid.RowsPresenterEstimatedAvailableHeight = finalSize.Height;
-                }
             }
 
             OwningGrid.OnFillerColumnWidthNeeded(finalSize.Width);
@@ -167,7 +148,6 @@ namespace Avalonia.Controls.Primitives
             // The DataGrid uses the RowsPresenter available size in order to autogrow
             // and calculate the scrollbars
             OwningGrid.RowsPresenterAvailableSize = availableSize;
-            OwningGrid.RowsPresenterEstimatedAvailableHeight = CalculateEstimatedAvailableHeight(availableSize);
 
             OwningGrid.OnRowsMeasure();