diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs index 90a27d0b31..98cd5aad02 100644 --- a/src/Avalonia.Controls/Grid.cs +++ b/src/Avalonia.Controls/Grid.cs @@ -1,601 +1,601 @@ -// 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.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reactive.Linq; -using System.Runtime.CompilerServices; -using Avalonia.Collections; -using Avalonia.Controls.Utils; -using Avalonia.VisualTree; -using JetBrains.Annotations; - -namespace Avalonia.Controls -{ - /// - /// Lays out child controls according to a grid. - /// - public class Grid : Panel - { - /// - /// Defines the Column attached property. - /// - public static readonly AttachedProperty ColumnProperty = - AvaloniaProperty.RegisterAttached( - "Column", - validate: ValidateColumn); - - /// - /// Defines the ColumnSpan attached property. - /// - public static readonly AttachedProperty ColumnSpanProperty = - AvaloniaProperty.RegisterAttached("ColumnSpan", 1); - - /// - /// Defines the Row attached property. - /// - public static readonly AttachedProperty RowProperty = - AvaloniaProperty.RegisterAttached( - "Row", - validate: ValidateRow); - - /// - /// Defines the RowSpan attached property. - /// - public static readonly AttachedProperty RowSpanProperty = - AvaloniaProperty.RegisterAttached("RowSpan", 1); - - public static readonly AttachedProperty IsSharedSizeScopeProperty = - AvaloniaProperty.RegisterAttached("IsSharedSizeScope", false); - - protected override void OnMeasureInvalidated() - { - base.OnMeasureInvalidated(); - _sharedSizeHost?.InvalidateMeasure(this); - } - - private SharedSizeScopeHost _sharedSizeHost; - - /// - /// Defines the SharedSizeScopeHost private property. - /// The ampersands are used to make accessing the property via xaml inconvenient. - /// - internal static readonly AttachedProperty s_sharedSizeScopeHostProperty = - AvaloniaProperty.RegisterAttached("&&SharedSizeScopeHost"); - - private ColumnDefinitions _columnDefinitions; - - private RowDefinitions _rowDefinitions; - - static Grid() - { - AffectsParentMeasure(ColumnProperty, ColumnSpanProperty, RowProperty, RowSpanProperty); - IsSharedSizeScopeProperty.Changed.AddClassHandler(IsSharedSizeScopeChanged); - } - - public Grid() - { - this.AttachedToVisualTree += Grid_AttachedToVisualTree; - this.DetachedFromVisualTree += Grid_DetachedFromVisualTree; - } - - /// - /// Gets or sets the columns definitions for the grid. - /// - public ColumnDefinitions ColumnDefinitions - { - get - { - if (_columnDefinitions == null) - { - ColumnDefinitions = new ColumnDefinitions(); - } - - return _columnDefinitions; - } - - set - { - if (_columnDefinitions != null) - { - throw new NotSupportedException("Reassigning ColumnDefinitions not yet implemented."); - } - - _columnDefinitions = value; - _columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); - _columnDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); - } - } - - /// - /// Gets or sets the row definitions for the grid. - /// - public RowDefinitions RowDefinitions - { - get - { - if (_rowDefinitions == null) - { - RowDefinitions = new RowDefinitions(); - } - - return _rowDefinitions; - } - - set - { - if (_rowDefinitions != null) - { - throw new NotSupportedException("Reassigning RowDefinitions not yet implemented."); - } - - _rowDefinitions = value; - _rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); - _rowDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); - } - } - - /// - /// Gets the value of the Column attached property for a control. - /// - /// The control. - /// The control's column. - public static int GetColumn(AvaloniaObject element) - { - return element.GetValue(ColumnProperty); - } - - /// - /// Gets the value of the ColumnSpan attached property for a control. - /// - /// The control. - /// The control's column span. - public static int GetColumnSpan(AvaloniaObject element) - { - return element.GetValue(ColumnSpanProperty); - } - - /// - /// Gets the value of the Row attached property for a control. - /// - /// The control. - /// The control's row. - public static int GetRow(AvaloniaObject element) - { - return element.GetValue(RowProperty); - } - - /// - /// Gets the value of the RowSpan attached property for a control. - /// - /// The control. - /// The control's row span. - public static int GetRowSpan(AvaloniaObject element) - { - return element.GetValue(RowSpanProperty); - } - - - /// - /// Gets the value of the IsSharedSizeScope attached property for a control. - /// - /// The control. - /// The control's IsSharedSizeScope value. - public static bool GetIsSharedSizeScope(AvaloniaObject element) - { - return element.GetValue(IsSharedSizeScopeProperty); - } - - /// - /// Sets the value of the Column attached property for a control. - /// - /// The control. - /// The column value. - public static void SetColumn(AvaloniaObject element, int value) - { - element.SetValue(ColumnProperty, value); - } - - /// - /// Sets the value of the ColumnSpan attached property for a control. - /// - /// The control. - /// The column span value. - public static void SetColumnSpan(AvaloniaObject element, int value) - { - element.SetValue(ColumnSpanProperty, value); - } - - /// - /// Sets the value of the Row attached property for a control. - /// - /// The control. - /// The row value. - public static void SetRow(AvaloniaObject element, int value) - { - element.SetValue(RowProperty, value); - } - - /// - /// Sets the value of the RowSpan attached property for a control. - /// - /// The control. - /// The row span value. - public static void SetRowSpan(AvaloniaObject element, int value) - { - element.SetValue(RowSpanProperty, value); - } - - /// - /// Sets the value of IsSharedSizeScope property for a control. - /// - /// The control. - /// The IsSharedSizeScope value. - public static void SetIsSharedSizeScope(AvaloniaObject element, bool value) - { - element.SetValue(IsSharedSizeScopeProperty, value); - } - - /// - /// Gets the result of the last column measurement. - /// Use this result to reduce the arrange calculation. - /// - private GridLayout.MeasureResult _columnMeasureCache; - - /// - /// Gets the result of the last row measurement. - /// Use this result to reduce the arrange calculation. - /// - private GridLayout.MeasureResult _rowMeasureCache; - - /// - /// Gets the row layout as of the last measure. - /// - private GridLayout _rowLayoutCache; - - /// - /// Gets the column layout as of the last measure. - /// - private GridLayout _columnLayoutCache; - - /// - /// Measures the grid. - /// - /// The available size. - /// The desired size of the control. - protected override Size MeasureOverride(Size constraint) - { - // Situation 1/2: - // If the grid doesn't have any column/row definitions, it behaves like a normal panel. - // GridLayout supports this situation but we handle this separately for performance. - - if (ColumnDefinitions.Count == 0 && RowDefinitions.Count == 0) - { - var maxWidth = 0.0; - var maxHeight = 0.0; - foreach (var child in Children.OfType()) - { - child.Measure(constraint); - maxWidth = Math.Max(maxWidth, child.DesiredSize.Width); - maxHeight = Math.Max(maxHeight, child.DesiredSize.Height); - } - - maxWidth = Math.Min(maxWidth, constraint.Width); - maxHeight = Math.Min(maxHeight, constraint.Height); - return new Size(maxWidth, maxHeight); - } - - // Situation 2/2: - // If the grid defines some columns or rows. - // Debug Tip: - // - GridLayout doesn't hold any state, so you can drag the debugger execution - // arrow back to any statements and re-run them without any side-effect. - - var measureCache = new Dictionary(); - var (safeColumns, safeRows) = GetSafeColumnRows(); - var columnLayout = new GridLayout(ColumnDefinitions); - var rowLayout = new GridLayout(RowDefinitions); - // Note: If a child stays in a * or Auto column/row, use constraint to measure it. - columnLayout.AppendMeasureConventions(safeColumns, child => MeasureOnce(child, constraint).Width); - rowLayout.AppendMeasureConventions(safeRows, child => MeasureOnce(child, constraint).Height); - - // Calculate measurement. - var columnResult = columnLayout.Measure(constraint.Width); - var rowResult = rowLayout.Measure(constraint.Height); - - // Use the results of the measurement to measure the rest of the children. - foreach (var child in Children.OfType()) - { - var (column, columnSpan) = safeColumns[child]; - var (row, rowSpan) = safeRows[child]; - var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum(); - var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum(); - - MeasureOnce(child, new Size(width, height)); - } - - // Cache the measure result and return the desired size. - _columnMeasureCache = columnResult; - _rowMeasureCache = rowResult; - _rowLayoutCache = rowLayout; - _columnLayoutCache = columnLayout; - - if (_sharedSizeHost?.ParticipatesInScope(this) ?? false) - { - _sharedSizeHost.UpdateMeasureStatus(this, rowResult, columnResult); - } - - return new Size(columnResult.DesiredLength, rowResult.DesiredLength); - - // Measure each child only once. - // If a child has been measured, it will just return the desired size. - Size MeasureOnce(Control child, Size size) - { - if (measureCache.TryGetValue(child, out var desiredSize)) - { - return desiredSize; - } - - child.Measure(size); - desiredSize = child.DesiredSize; - measureCache[child] = desiredSize; - return desiredSize; - } - } - - /// - /// Arranges the grid's children. - /// - /// The size allocated to the control. - /// The space taken. - protected override Size ArrangeOverride(Size finalSize) - { - // Situation 1/2: - // If the grid doesn't have any column/row definitions, it behaves like a normal panel. - // GridLayout supports this situation but we handle this separately for performance. - - if (ColumnDefinitions.Count == 0 && RowDefinitions.Count == 0) - { - foreach (var child in Children.OfType()) - { - child.Arrange(new Rect(finalSize)); - } - - return finalSize; - } - - // Situation 2/2: - // If the grid defines some columns or rows. - // Debug Tip: - // - GridLayout doesn't hold any state, so you can drag the debugger execution - // arrow back to any statements and re-run them without any side-effect. - - var (safeColumns, safeRows) = GetSafeColumnRows(); - var columnLayout = _columnLayoutCache; - var rowLayout = _rowLayoutCache; - - var rowCache = _rowMeasureCache; - var columnCache = _columnMeasureCache; - - if (_sharedSizeHost?.ParticipatesInScope(this) ?? false) - { - (rowCache, columnCache) = _sharedSizeHost.HandleArrange(this, _rowMeasureCache, _columnMeasureCache); +// // 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.Generic; +// using System.Diagnostics; +// using System.Linq; +// using System.Reactive.Linq; +// using System.Runtime.CompilerServices; +// using Avalonia.Collections; +// using Avalonia.Controls.Utils; +// using Avalonia.VisualTree; +// using JetBrains.Annotations; + +// namespace Avalonia.Controls +// { +// /// +// /// Lays out child controls according to a grid. +// /// +// public class Grid : Panel +// { +// /// +// /// Defines the Column attached property. +// /// +// public static readonly AttachedProperty ColumnProperty = +// AvaloniaProperty.RegisterAttached( +// "Column", +// validate: ValidateColumn); + +// /// +// /// Defines the ColumnSpan attached property. +// /// +// public static readonly AttachedProperty ColumnSpanProperty = +// AvaloniaProperty.RegisterAttached("ColumnSpan", 1); + +// /// +// /// Defines the Row attached property. +// /// +// public static readonly AttachedProperty RowProperty = +// AvaloniaProperty.RegisterAttached( +// "Row", +// validate: ValidateRow); + +// /// +// /// Defines the RowSpan attached property. +// /// +// public static readonly AttachedProperty RowSpanProperty = +// AvaloniaProperty.RegisterAttached("RowSpan", 1); + +// public static readonly AttachedProperty IsSharedSizeScopeProperty = +// AvaloniaProperty.RegisterAttached("IsSharedSizeScope", false); + +// protected override void OnMeasureInvalidated() +// { +// base.OnMeasureInvalidated(); +// _sharedSizeHost?.InvalidateMeasure(this); +// } + +// private SharedSizeScopeHost _sharedSizeHost; + +// /// +// /// Defines the SharedSizeScopeHost private property. +// /// The ampersands are used to make accessing the property via xaml inconvenient. +// /// +// internal static readonly AttachedProperty s_sharedSizeScopeHostProperty = +// AvaloniaProperty.RegisterAttached("&&SharedSizeScopeHost"); + +// private ColumnDefinitions _columnDefinitions; + +// private RowDefinitions _rowDefinitions; + +// static Grid() +// { +// AffectsParentMeasure(ColumnProperty, ColumnSpanProperty, RowProperty, RowSpanProperty); +// IsSharedSizeScopeProperty.Changed.AddClassHandler(IsSharedSizeScopeChanged); +// } + +// public Grid() +// { +// this.AttachedToVisualTree += Grid_AttachedToVisualTree; +// this.DetachedFromVisualTree += Grid_DetachedFromVisualTree; +// } + +// /// +// /// Gets or sets the columns definitions for the grid. +// /// +// public ColumnDefinitions ColumnDefinitions +// { +// get +// { +// if (_columnDefinitions == null) +// { +// ColumnDefinitions = new ColumnDefinitions(); +// } + +// return _columnDefinitions; +// } + +// set +// { +// if (_columnDefinitions != null) +// { +// throw new NotSupportedException("Reassigning ColumnDefinitions not yet implemented."); +// } + +// _columnDefinitions = value; +// _columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); +// _columnDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); +// } +// } + +// /// +// /// Gets or sets the row definitions for the grid. +// /// +// public RowDefinitions RowDefinitions +// { +// get +// { +// if (_rowDefinitions == null) +// { +// RowDefinitions = new RowDefinitions(); +// } + +// return _rowDefinitions; +// } + +// set +// { +// if (_rowDefinitions != null) +// { +// throw new NotSupportedException("Reassigning RowDefinitions not yet implemented."); +// } + +// _rowDefinitions = value; +// _rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); +// _rowDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); +// } +// } + +// /// +// /// Gets the value of the Column attached property for a control. +// /// +// /// The control. +// /// The control's column. +// public static int GetColumn(AvaloniaObject element) +// { +// return element.GetValue(ColumnProperty); +// } + +// /// +// /// Gets the value of the ColumnSpan attached property for a control. +// /// +// /// The control. +// /// The control's column span. +// public static int GetColumnSpan(AvaloniaObject element) +// { +// return element.GetValue(ColumnSpanProperty); +// } + +// /// +// /// Gets the value of the Row attached property for a control. +// /// +// /// The control. +// /// The control's row. +// public static int GetRow(AvaloniaObject element) +// { +// return element.GetValue(RowProperty); +// } + +// /// +// /// Gets the value of the RowSpan attached property for a control. +// /// +// /// The control. +// /// The control's row span. +// public static int GetRowSpan(AvaloniaObject element) +// { +// return element.GetValue(RowSpanProperty); +// } + + +// /// +// /// Gets the value of the IsSharedSizeScope attached property for a control. +// /// +// /// The control. +// /// The control's IsSharedSizeScope value. +// public static bool GetIsSharedSizeScope(AvaloniaObject element) +// { +// return element.GetValue(IsSharedSizeScopeProperty); +// } + +// /// +// /// Sets the value of the Column attached property for a control. +// /// +// /// The control. +// /// The column value. +// public static void SetColumn(AvaloniaObject element, int value) +// { +// element.SetValue(ColumnProperty, value); +// } + +// /// +// /// Sets the value of the ColumnSpan attached property for a control. +// /// +// /// The control. +// /// The column span value. +// public static void SetColumnSpan(AvaloniaObject element, int value) +// { +// element.SetValue(ColumnSpanProperty, value); +// } + +// /// +// /// Sets the value of the Row attached property for a control. +// /// +// /// The control. +// /// The row value. +// public static void SetRow(AvaloniaObject element, int value) +// { +// element.SetValue(RowProperty, value); +// } + +// /// +// /// Sets the value of the RowSpan attached property for a control. +// /// +// /// The control. +// /// The row span value. +// public static void SetRowSpan(AvaloniaObject element, int value) +// { +// element.SetValue(RowSpanProperty, value); +// } + +// /// +// /// Sets the value of IsSharedSizeScope property for a control. +// /// +// /// The control. +// /// The IsSharedSizeScope value. +// public static void SetIsSharedSizeScope(AvaloniaObject element, bool value) +// { +// element.SetValue(IsSharedSizeScopeProperty, value); +// } + +// /// +// /// Gets the result of the last column measurement. +// /// Use this result to reduce the arrange calculation. +// /// +// private GridLayout.MeasureResult _columnMeasureCache; + +// /// +// /// Gets the result of the last row measurement. +// /// Use this result to reduce the arrange calculation. +// /// +// private GridLayout.MeasureResult _rowMeasureCache; + +// /// +// /// Gets the row layout as of the last measure. +// /// +// private GridLayout _rowLayoutCache; + +// /// +// /// Gets the column layout as of the last measure. +// /// +// private GridLayout _columnLayoutCache; + +// /// +// /// Measures the grid. +// /// +// /// The available size. +// /// The desired size of the control. +// protected override Size MeasureOverride(Size constraint) +// { +// // Situation 1/2: +// // If the grid doesn't have any column/row definitions, it behaves like a normal panel. +// // GridLayout supports this situation but we handle this separately for performance. + +// if (ColumnDefinitions.Count == 0 && RowDefinitions.Count == 0) +// { +// var maxWidth = 0.0; +// var maxHeight = 0.0; +// foreach (var child in Children.OfType()) +// { +// child.Measure(constraint); +// maxWidth = Math.Max(maxWidth, child.DesiredSize.Width); +// maxHeight = Math.Max(maxHeight, child.DesiredSize.Height); +// } + +// maxWidth = Math.Min(maxWidth, constraint.Width); +// maxHeight = Math.Min(maxHeight, constraint.Height); +// return new Size(maxWidth, maxHeight); +// } + +// // Situation 2/2: +// // If the grid defines some columns or rows. +// // Debug Tip: +// // - GridLayout doesn't hold any state, so you can drag the debugger execution +// // arrow back to any statements and re-run them without any side-effect. + +// var measureCache = new Dictionary(); +// var (safeColumns, safeRows) = GetSafeColumnRows(); +// var columnLayout = new GridLayout(ColumnDefinitions); +// var rowLayout = new GridLayout(RowDefinitions); +// // Note: If a child stays in a * or Auto column/row, use constraint to measure it. +// columnLayout.AppendMeasureConventions(safeColumns, child => MeasureOnce(child, constraint).Width); +// rowLayout.AppendMeasureConventions(safeRows, child => MeasureOnce(child, constraint).Height); + +// // Calculate measurement. +// var columnResult = columnLayout.Measure(constraint.Width); +// var rowResult = rowLayout.Measure(constraint.Height); + +// // Use the results of the measurement to measure the rest of the children. +// foreach (var child in Children.OfType()) +// { +// var (column, columnSpan) = safeColumns[child]; +// var (row, rowSpan) = safeRows[child]; +// var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum(); +// var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum(); + +// MeasureOnce(child, new Size(width, height)); +// } + +// // Cache the measure result and return the desired size. +// _columnMeasureCache = columnResult; +// _rowMeasureCache = rowResult; +// _rowLayoutCache = rowLayout; +// _columnLayoutCache = columnLayout; + +// if (_sharedSizeHost?.ParticipatesInScope(this) ?? false) +// { +// _sharedSizeHost.UpdateMeasureStatus(this, rowResult, columnResult); +// } + +// return new Size(columnResult.DesiredLength, rowResult.DesiredLength); + +// // Measure each child only once. +// // If a child has been measured, it will just return the desired size. +// Size MeasureOnce(Control child, Size size) +// { +// if (measureCache.TryGetValue(child, out var desiredSize)) +// { +// return desiredSize; +// } + +// child.Measure(size); +// desiredSize = child.DesiredSize; +// measureCache[child] = desiredSize; +// return desiredSize; +// } +// } + +// /// +// /// Arranges the grid's children. +// /// +// /// The size allocated to the control. +// /// The space taken. +// protected override Size ArrangeOverride(Size finalSize) +// { +// // Situation 1/2: +// // If the grid doesn't have any column/row definitions, it behaves like a normal panel. +// // GridLayout supports this situation but we handle this separately for performance. + +// if (ColumnDefinitions.Count == 0 && RowDefinitions.Count == 0) +// { +// foreach (var child in Children.OfType()) +// { +// child.Arrange(new Rect(finalSize)); +// } + +// return finalSize; +// } + +// // Situation 2/2: +// // If the grid defines some columns or rows. +// // Debug Tip: +// // - GridLayout doesn't hold any state, so you can drag the debugger execution +// // arrow back to any statements and re-run them without any side-effect. + +// var (safeColumns, safeRows) = GetSafeColumnRows(); +// var columnLayout = _columnLayoutCache; +// var rowLayout = _rowLayoutCache; + +// var rowCache = _rowMeasureCache; +// var columnCache = _columnMeasureCache; + +// if (_sharedSizeHost?.ParticipatesInScope(this) ?? false) +// { +// (rowCache, columnCache) = _sharedSizeHost.HandleArrange(this, _rowMeasureCache, _columnMeasureCache); - rowCache = rowLayout.Measure(finalSize.Height, rowCache.LeanLengthList); - columnCache = columnLayout.Measure(finalSize.Width, columnCache.LeanLengthList); - } - - // Calculate for arrange result. - var columnResult = columnLayout.Arrange(finalSize.Width, columnCache); - var rowResult = rowLayout.Arrange(finalSize.Height, rowCache); - // Arrange the children. - foreach (var child in Children.OfType()) - { - var (column, columnSpan) = safeColumns[child]; - var (row, rowSpan) = safeRows[child]; - var x = Enumerable.Range(0, column).Sum(c => columnResult.LengthList[c]); - var y = Enumerable.Range(0, row).Sum(r => rowResult.LengthList[r]); - var width = Enumerable.Range(column, columnSpan).Sum(c => columnResult.LengthList[c]); - var height = Enumerable.Range(row, rowSpan).Sum(r => rowResult.LengthList[r]); - child.Arrange(new Rect(x, y, width, height)); - } - - // Assign the actual width. - for (var i = 0; i < ColumnDefinitions.Count; i++) - { - ColumnDefinitions[i].ActualWidth = columnResult.LengthList[i]; - } - - // Assign the actual height. - for (var i = 0; i < RowDefinitions.Count; i++) - { - RowDefinitions[i].ActualHeight = rowResult.LengthList[i]; - } - - // Return the render size. - return finalSize; - } - - /// - /// Tests whether this grid belongs to a shared size scope. - /// - /// True if the grid is registered in a shared size scope. - internal bool HasSharedSizeScope() - { - return _sharedSizeHost != null; - } - - /// - /// Called when the SharedSizeScope for a given grid has changed. - /// Unregisters the grid from it's current scope and finds a new one (if any) - /// - /// - /// This method, while not efficient, correctly handles nested scopes, with any order of scope changes. - /// - internal void SharedScopeChanged() - { - _sharedSizeHost?.UnegisterGrid(this); - - _sharedSizeHost = null; - var scope = this.GetVisualAncestors().OfType() - .FirstOrDefault(c => c.GetValue(IsSharedSizeScopeProperty)); - - if (scope != null) - { - _sharedSizeHost = scope.GetValue(s_sharedSizeScopeHostProperty); - _sharedSizeHost.RegisterGrid(this); - } - - InvalidateMeasure(); - } - - /// - /// Callback when a grid is attached to the visual tree. Finds the innermost SharedSizeScope and registers the grid - /// in it. - /// - /// The source of the event. - /// The event arguments. - private void Grid_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) - { - var scope = - new Control[] { this }.Concat(this.GetVisualAncestors().OfType()) - .FirstOrDefault(c => c.GetValue(IsSharedSizeScopeProperty)); - - if (_sharedSizeHost != null) - throw new AvaloniaInternalException("Shared size scope already present when attaching to visual tree!"); - - if (scope != null) - { - _sharedSizeHost = scope.GetValue(s_sharedSizeScopeHostProperty); - _sharedSizeHost.RegisterGrid(this); - } - } - - /// - /// Callback when a grid is detached from the visual tree. Unregisters the grid from its SharedSizeScope if any. - /// - /// The source of the event. - /// The event arguments. - private void Grid_DetachedFromVisualTree(object sender, VisualTreeAttachmentEventArgs e) - { - _sharedSizeHost?.UnegisterGrid(this); - _sharedSizeHost = null; - } - - - /// - /// Get the safe column/columnspan and safe row/rowspan. - /// This method ensures that none of the children has a column/row outside the bounds of the definitions. - /// - [Pure] - private (Dictionary safeColumns, - Dictionary safeRows) GetSafeColumnRows() - { - var columnCount = ColumnDefinitions.Count; - var rowCount = RowDefinitions.Count; - columnCount = columnCount == 0 ? 1 : columnCount; - rowCount = rowCount == 0 ? 1 : rowCount; - var safeColumns = Children.OfType().ToDictionary(child => child, - child => GetSafeSpan(columnCount, GetColumn(child), GetColumnSpan(child))); - var safeRows = Children.OfType().ToDictionary(child => child, - child => GetSafeSpan(rowCount, GetRow(child), GetRowSpan(child))); - return (safeColumns, safeRows); - } - - /// - /// Gets the safe row/column and rowspan/columnspan for a specified range. - /// The user may assign row/column properties outside the bounds of the row/column count, this method coerces them inside. - /// - /// The row or column count. - /// The row or column that the user assigned. - /// The rowspan or columnspan that the user assigned. - /// The safe row/column and rowspan/columnspan. - [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)] - private static (int index, int span) GetSafeSpan(int length, int userIndex, int userSpan) - { - var index = userIndex; - var span = userSpan; - - if (index < 0) - { - span = index + span; - index = 0; - } - - if (span <= 0) - { - span = 1; - } - - if (userIndex >= length) - { - index = length - 1; - span = 1; - } - else if (userIndex + userSpan > length) - { - span = length - userIndex; - } - - return (index, span); - } - - private static int ValidateColumn(AvaloniaObject o, int value) - { - if (value < 0) - { - throw new ArgumentException("Invalid Grid.Column value."); - } - - return value; - } - - private static int ValidateRow(AvaloniaObject o, int value) - { - if (value < 0) - { - throw new ArgumentException("Invalid Grid.Row value."); - } - - return value; - } - - /// - /// Called when the value of changes for a control. - /// - /// The control that triggered the change. - /// Change arguments. - private static void IsSharedSizeScopeChanged(Control source, AvaloniaPropertyChangedEventArgs arg2) - { - var shouldDispose = (arg2.OldValue is bool d) && d; - if (shouldDispose) - { - var host = source.GetValue(s_sharedSizeScopeHostProperty) as SharedSizeScopeHost; - if (host == null) - throw new AvaloniaInternalException("SharedScopeHost wasn't set when IsSharedSizeScope was true!"); - host.Dispose(); - source.ClearValue(s_sharedSizeScopeHostProperty); - } - - var shouldAssign = (arg2.NewValue is bool a) && a; - if (shouldAssign) - { - if (source.GetValue(s_sharedSizeScopeHostProperty) != null) - throw new AvaloniaInternalException("SharedScopeHost was already set when IsSharedSizeScope is only now being set to true!"); - source.SetValue(s_sharedSizeScopeHostProperty, new SharedSizeScopeHost()); - } - - // if the scope has changed, notify the descendant grids that they need to update. - if (source.GetVisualRoot() != null && shouldAssign || shouldDispose) - { - var participatingGrids = new[] { source }.Concat(source.GetVisualDescendants()).OfType(); - - foreach (var grid in participatingGrids) - grid.SharedScopeChanged(); - - } - } - } -} +// rowCache = rowLayout.Measure(finalSize.Height, rowCache.LeanLengthList); +// columnCache = columnLayout.Measure(finalSize.Width, columnCache.LeanLengthList); +// } + +// // Calculate for arrange result. +// var columnResult = columnLayout.Arrange(finalSize.Width, columnCache); +// var rowResult = rowLayout.Arrange(finalSize.Height, rowCache); +// // Arrange the children. +// foreach (var child in Children.OfType()) +// { +// var (column, columnSpan) = safeColumns[child]; +// var (row, rowSpan) = safeRows[child]; +// var x = Enumerable.Range(0, column).Sum(c => columnResult.LengthList[c]); +// var y = Enumerable.Range(0, row).Sum(r => rowResult.LengthList[r]); +// var width = Enumerable.Range(column, columnSpan).Sum(c => columnResult.LengthList[c]); +// var height = Enumerable.Range(row, rowSpan).Sum(r => rowResult.LengthList[r]); +// child.Arrange(new Rect(x, y, width, height)); +// } + +// // Assign the actual width. +// for (var i = 0; i < ColumnDefinitions.Count; i++) +// { +// ColumnDefinitions[i].ActualWidth = columnResult.LengthList[i]; +// } + +// // Assign the actual height. +// for (var i = 0; i < RowDefinitions.Count; i++) +// { +// RowDefinitions[i].ActualHeight = rowResult.LengthList[i]; +// } + +// // Return the render size. +// return finalSize; +// } + +// /// +// /// Tests whether this grid belongs to a shared size scope. +// /// +// /// True if the grid is registered in a shared size scope. +// internal bool HasSharedSizeScope() +// { +// return _sharedSizeHost != null; +// } + +// /// +// /// Called when the SharedSizeScope for a given grid has changed. +// /// Unregisters the grid from it's current scope and finds a new one (if any) +// /// +// /// +// /// This method, while not efficient, correctly handles nested scopes, with any order of scope changes. +// /// +// internal void SharedScopeChanged() +// { +// _sharedSizeHost?.UnegisterGrid(this); + +// _sharedSizeHost = null; +// var scope = this.GetVisualAncestors().OfType() +// .FirstOrDefault(c => c.GetValue(IsSharedSizeScopeProperty)); + +// if (scope != null) +// { +// _sharedSizeHost = scope.GetValue(s_sharedSizeScopeHostProperty); +// _sharedSizeHost.RegisterGrid(this); +// } + +// InvalidateMeasure(); +// } + +// /// +// /// Callback when a grid is attached to the visual tree. Finds the innermost SharedSizeScope and registers the grid +// /// in it. +// /// +// /// The source of the event. +// /// The event arguments. +// private void Grid_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) +// { +// var scope = +// new Control[] { this }.Concat(this.GetVisualAncestors().OfType()) +// .FirstOrDefault(c => c.GetValue(IsSharedSizeScopeProperty)); + +// if (_sharedSizeHost != null) +// throw new AvaloniaInternalException("Shared size scope already present when attaching to visual tree!"); + +// if (scope != null) +// { +// _sharedSizeHost = scope.GetValue(s_sharedSizeScopeHostProperty); +// _sharedSizeHost.RegisterGrid(this); +// } +// } + +// /// +// /// Callback when a grid is detached from the visual tree. Unregisters the grid from its SharedSizeScope if any. +// /// +// /// The source of the event. +// /// The event arguments. +// private void Grid_DetachedFromVisualTree(object sender, VisualTreeAttachmentEventArgs e) +// { +// _sharedSizeHost?.UnegisterGrid(this); +// _sharedSizeHost = null; +// } + + +// /// +// /// Get the safe column/columnspan and safe row/rowspan. +// /// This method ensures that none of the children has a column/row outside the bounds of the definitions. +// /// +// [Pure] +// private (Dictionary safeColumns, +// Dictionary safeRows) GetSafeColumnRows() +// { +// var columnCount = ColumnDefinitions.Count; +// var rowCount = RowDefinitions.Count; +// columnCount = columnCount == 0 ? 1 : columnCount; +// rowCount = rowCount == 0 ? 1 : rowCount; +// var safeColumns = Children.OfType().ToDictionary(child => child, +// child => GetSafeSpan(columnCount, GetColumn(child), GetColumnSpan(child))); +// var safeRows = Children.OfType().ToDictionary(child => child, +// child => GetSafeSpan(rowCount, GetRow(child), GetRowSpan(child))); +// return (safeColumns, safeRows); +// } + +// /// +// /// Gets the safe row/column and rowspan/columnspan for a specified range. +// /// The user may assign row/column properties outside the bounds of the row/column count, this method coerces them inside. +// /// +// /// The row or column count. +// /// The row or column that the user assigned. +// /// The rowspan or columnspan that the user assigned. +// /// The safe row/column and rowspan/columnspan. +// [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)] +// private static (int index, int span) GetSafeSpan(int length, int userIndex, int userSpan) +// { +// var index = userIndex; +// var span = userSpan; + +// if (index < 0) +// { +// span = index + span; +// index = 0; +// } + +// if (span <= 0) +// { +// span = 1; +// } + +// if (userIndex >= length) +// { +// index = length - 1; +// span = 1; +// } +// else if (userIndex + userSpan > length) +// { +// span = length - userIndex; +// } + +// return (index, span); +// } + +// private static int ValidateColumn(AvaloniaObject o, int value) +// { +// if (value < 0) +// { +// throw new ArgumentException("Invalid Grid.Column value."); +// } + +// return value; +// } + +// private static int ValidateRow(AvaloniaObject o, int value) +// { +// if (value < 0) +// { +// throw new ArgumentException("Invalid Grid.Row value."); +// } + +// return value; +// } + +// /// +// /// Called when the value of changes for a control. +// /// +// /// The control that triggered the change. +// /// Change arguments. +// private static void IsSharedSizeScopeChanged(Control source, AvaloniaPropertyChangedEventArgs arg2) +// { +// var shouldDispose = (arg2.OldValue is bool d) && d; +// if (shouldDispose) +// { +// var host = source.GetValue(s_sharedSizeScopeHostProperty) as SharedSizeScopeHost; +// if (host == null) +// throw new AvaloniaInternalException("SharedScopeHost wasn't set when IsSharedSizeScope was true!"); +// host.Dispose(); +// source.ClearValue(s_sharedSizeScopeHostProperty); +// } + +// var shouldAssign = (arg2.NewValue is bool a) && a; +// if (shouldAssign) +// { +// if (source.GetValue(s_sharedSizeScopeHostProperty) != null) +// throw new AvaloniaInternalException("SharedScopeHost was already set when IsSharedSizeScope is only now being set to true!"); +// source.SetValue(s_sharedSizeScopeHostProperty, new SharedSizeScopeHost()); +// } + +// // if the scope has changed, notify the descendant grids that they need to update. +// if (source.GetVisualRoot() != null && shouldAssign || shouldDispose) +// { +// var participatingGrids = new[] { source }.Concat(source.GetVisualDescendants()).OfType(); + +// foreach (var grid in participatingGrids) +// grid.SharedScopeChanged(); + +// } +// } +// } +// } diff --git a/src/Avalonia.Controls/GridWPF.cs b/src/Avalonia.Controls/GridWPF.cs index ff006a5c1b..fc498608e3 100644 --- a/src/Avalonia.Controls/GridWPF.cs +++ b/src/Avalonia.Controls/GridWPF.cs @@ -17,7 +17,7 @@ using Avalonia.Media; using Avalonia; using System.Collections; -namespace System.Windows.Controls +namespace Avalonia.Controls { /// /// Grid @@ -25,284 +25,108 @@ namespace System.Windows.Controls public class Grid : Panel { /// - /// + /// Defines the Column attached property. /// - protected internal override IEnumerator LogicalChildren - { - get - { - // empty panel or a panel being used as the items - // host has *no* logical Children; give empty enumerator - bool noChildren = (base.VisualChildrenCount == 0) || IsItemsHost; - - if (noChildren) - { - ExtendedData extData = ExtData; - - if (extData == null - || ((extData.ColumnDefinitions == null || extData.ColumnDefinitions.Count == 0) - && (extData.RowDefinitions == null || extData.RowDefinitions.Count == 0)) - ) - { - // grid is empty - return EmptyEnumerator.Instance; - } - } - - return (new GridChildrenCollectionEnumeratorSimple(this, !noChildren)); - } - } + public static readonly AttachedProperty ColumnProperty = + AvaloniaProperty.RegisterAttached( + "Column", + validate: ValidateColumn); /// - /// Helper for setting Column property on a Control. + /// Defines the ColumnSpan attached property. /// - /// Control to set Column property on. - /// Column property value. - public static void SetColumn(Control element, int value) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } - - element.SetValue(ColumnProperty, value); - } + public static readonly AttachedProperty ColumnSpanProperty = + AvaloniaProperty.RegisterAttached("ColumnSpan", 1); /// - /// Helper for reading Column property from a Control. + /// Defines the Row attached property. /// - /// Control to read Column property from. - /// Column property value. - public static int GetColumn(Control element) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } - - return ((int)element.GetValue(ColumnProperty)); - } - - /// - /// Helper for setting Row property on a Control. - /// - /// Control to set Row property on. - /// Row property value. - public static void SetRow(Control element, int value) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } - - element.SetValue(RowProperty, value); - } + public static readonly AttachedProperty RowProperty = + AvaloniaProperty.RegisterAttached( + "Row", + validate: ValidateRow); /// - /// Helper for reading Row property from a Control. + /// Defines the RowSpan attached property. /// - /// Control to read Row property from. - /// Row property value. - [AttachedPropertyBrowsableForChildren()] - public static int GetRow(Control element) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } - - return ((int)element.GetValue(RowProperty)); - } - - /// - /// Helper for setting ColumnSpan property on a Control. - /// - /// Control to set ColumnSpan property on. - /// ColumnSpan property value. - public static void SetColumnSpan(Control element, int value) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } + public static readonly AttachedProperty RowSpanProperty = + AvaloniaProperty.RegisterAttached("RowSpan", 1); - element.SetValue(ColumnSpanProperty, value); - } + public static readonly AttachedProperty IsSharedSizeScopeProperty = + AvaloniaProperty.RegisterAttached("IsSharedSizeScope", false); /// - /// Helper for reading ColumnSpan property from a Control. + /// ShowGridLines property. /// - /// Control to read ColumnSpan property from. - /// ColumnSpan property value. - [AttachedPropertyBrowsableForChildren()] - public static int GetColumnSpan(Control element) + public bool ShowGridLines { - if (element == null) - { - throw new ArgumentNullException("element"); - } - - return ((int)element.GetValue(ColumnSpanProperty)); + get { return (CheckFlagsAnd(Flags.ShowGridLinesPropertyValue)); } + set { SetValue(ShowGridLinesProperty, value); } } + private ColumnDefinitions _columnDefinitions; + private RowDefinitions _rowDefinitions; /// - /// Helper for setting RowSpan property on a Control. + /// Gets or sets the columns definitions for the grid. /// - /// Control to set RowSpan property on. - /// RowSpan property value. - public static void SetRowSpan(Control element, int value) + public ColumnDefinitions ColumnDefinitions { - if (element == null) + get { - throw new ArgumentNullException("element"); - } + if (_data == null) { _data = new ExtendedData(); } - element.SetValue(RowSpanProperty, value); - } + if (_columnDefinitions == null) + { + ColumnDefinitions = new ColumnDefinitions(); + } - /// - /// Helper for reading RowSpan property from a Control. - /// - /// Control to read RowSpan property from. - /// RowSpan property value. - public static int GetRowSpan(Control element) - { - if (element == null) - { - throw new ArgumentNullException("element"); + return _columnDefinitions; } - return ((int)element.GetValue(RowSpanProperty)); - } - - /// - /// Helper for setting IsSharedSizeScope property on a Control. - /// - /// Control to set IsSharedSizeScope property on. - /// IsSharedSizeScope property value. - public static void SetIsSharedSizeScope(Control element, bool value) - { - if (element == null) + set { - throw new ArgumentNullException("element"); - } - element.SetValue(IsSharedSizeScopeProperty, value); - } + if (_columnDefinitions != null) + { + throw new NotSupportedException("Reassigning ColumnDefinitions not yet implemented."); + } - /// - /// Helper for reading IsSharedSizeScope property from a Control. - /// - /// Control to read IsSharedSizeScope property from. - /// IsSharedSizeScope property value. - public static bool GetIsSharedSizeScope(Control element) - { - if (element == null) - { - throw new ArgumentNullException("element"); + _columnDefinitions = value; + _columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); + _columnDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); } - - return ((bool)element.GetValue(IsSharedSizeScopeProperty)); - } - - - //------------------------------------------------------ - // - // Public Properties - // - //------------------------------------------------------ - - #region Public Properties - - /// - /// ShowGridLines property. - /// - public bool ShowGridLines - { - get { return (CheckFlagsAnd(Flags.ShowGridLinesPropertyValue)); } - set { SetValue(ShowGridLinesProperty, value); } } /// - /// Returns a ColumnDefinitionCollection of column definitions. + /// Gets or sets the row definitions for the grid. /// - [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] - public ColumnDefinitionCollection ColumnDefinitions + public RowDefinitions RowDefinitions { get { if (_data == null) { _data = new ExtendedData(); } - if (_data.ColumnDefinitions == null) { _data.ColumnDefinitions = new ColumnDefinitionCollection(this); } - return (_data.ColumnDefinitions); - } - } - - /// - /// Returns a RowDefinitionCollection of row definitions. - /// - [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] - public RowDefinitionCollection RowDefinitions - { - get - { - if (_data == null) { _data = new ExtendedData(); } - if (_data.RowDefinitions == null) { _data.RowDefinitions = new RowDefinitionCollection(this); } + if (_rowDefinitions == null) + { + RowDefinitions = new RowDefinitions(); + } - return (_data.RowDefinitions); + return _rowDefinitions; } - } - - #endregion Public Properties - - //------------------------------------------------------ - // - // Protected Methods - // - //------------------------------------------------------ - - #region Protected Methods - /// - /// Derived class must implement to support Visual Children. The method must return - /// the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1. - /// - /// By default a Visual does not have any Children. - /// - /// Remark: - /// During this virtual call it is not valid to modify the Visual tree. - /// - protected override Visual GetVisualChild(int index) - { - // because "base.Count + 1" for GridLinesRenderer - // argument checking done at the base class - if (index == base.VisualChildrenCount) + set { - if (_gridLinesRenderer == null) + if (_rowDefinitions != null) { - throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); + throw new NotSupportedException("Reassigning RowDefinitions not yet implemented."); } - return _gridLinesRenderer; - } - else return base.GetVisualChild(index); - } - /// - /// Derived classes override this property to enable the Visual code to enumerate - /// the Visual Children. Derived classes need to return the number of Children - /// from this method. - /// - /// By default a Visual does not have any Children. - /// - /// Remark: During this virtual method the Visual tree must not be modified. - /// - protected override int VisualChildrenCount - { - //since GridLinesRenderer has not been added as a child, so we do not subtract - get { return base.VisualChildrenCount + (_gridLinesRenderer != null ? 1 : 0); } + _rowDefinitions = value; + _rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); + _rowDefinitions.CollectionChanged += (_, __) => InvalidateMeasure(); + } } - /// /// Content measurement. /// @@ -315,8 +139,6 @@ namespace System.Windows.Controls try { - EnterCounterScope(Counters.MeasureOverride); - ListenToNotifications = true; MeasureOverrideInProgress = true; @@ -330,8 +152,9 @@ namespace System.Windows.Controls if (child != null) { child.Measure(constraint); - gridDesiredSize.Width = Math.Max(gridDesiredSize.Width, child.DesiredSize.Width); - gridDesiredSize.Height = Math.Max(gridDesiredSize.Height, child.DesiredSize.Height); + gridDesiredSize = new Size( + Math.Max(gridDesiredSize.Width, child.DesiredSize.Width), + Math.Max(gridDesiredSize.Height, child.DesiredSize.Height)); } } } @@ -590,17 +413,14 @@ namespace System.Windows.Controls MeasureCellsGroup(extData.CellGroup4, constraint, false, false); - EnterCounter(Counters._CalculateDesiredSize); gridDesiredSize = new Size( CalculateDesiredSize(DefinitionsU), CalculateDesiredSize(DefinitionsV)); - ExitCounter(Counters._CalculateDesiredSize); } } finally { MeasureOverrideInProgress = false; - ExitCounterScope(Counters.MeasureOverride); } return (gridDesiredSize); @@ -614,17 +434,14 @@ namespace System.Windows.Controls { try { - EnterCounterScope(Counters.ArrangeOverride); ArrangeOverrideInProgress = true; if (_data == null) { - ControlCollection Children = InternalChildren; - for (int i = 0, count = Children.Count; i < count; ++i) { - Control child = Children[i]; + var child = Children[i]; if (child != null) { child.Arrange(new Rect(arrangeSize)); @@ -635,18 +452,12 @@ namespace System.Windows.Controls { Debug.Assert(DefinitionsU.Length > 0 && DefinitionsV.Length > 0); - EnterCounter(Counters._SetFinalSize); - SetFinalSize(DefinitionsU, arrangeSize.Width, true); SetFinalSize(DefinitionsV, arrangeSize.Height, false); - ExitCounter(Counters._SetFinalSize); - - ControlCollection Children = InternalChildren; - for (int currentCell = 0; currentCell < PrivateCells.Length; ++currentCell) { - Control cell = Children[currentCell]; + IControl cell = Children[currentCell]; if (cell == null) { continue; @@ -663,9 +474,7 @@ namespace System.Windows.Controls GetFinalSizeForRange(DefinitionsU, columnIndex, columnSpan), GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan)); - EnterCounter(Counters._ArrangeChildHelper2); cell.Arrange(cellRect); - ExitCounter(Counters._ArrangeChildHelper2); } // update render bound on grid lines renderer visual @@ -680,7 +489,6 @@ namespace System.Windows.Controls { SetValid(); ArrangeOverrideInProgress = false; - ExitCounterScope(Counters.ArrangeOverride); } return (arrangeSize); } @@ -697,7 +505,6 @@ namespace System.Windows.Controls base.OnVisualChildrenChanged(visualAdded, visualRemoved); } - #endregion Protected Methods //------------------------------------------------------ // @@ -821,15 +628,11 @@ namespace System.Windows.Controls /// private void ValidateCells() { - EnterCounter(Counters._ValidateCells); - if (CellsStructureDirty) { ValidateCellsCore(); CellsStructureDirty = false; } - - ExitCounter(Counters._ValidateCells); } /// @@ -837,7 +640,6 @@ namespace System.Windows.Controls /// private void ValidateCellsCore() { - ControlCollection Children = InternalChildren; ExtendedData extData = ExtData; extData.CellCachesCollection = new CellCache[Children.Count]; @@ -852,7 +654,7 @@ namespace System.Windows.Controls for (int i = PrivateCells.Length - 1; i >= 0; --i) { - Control child = Children[i]; + var child = Children[i]; if (child == null) { continue; @@ -1312,7 +1114,7 @@ namespace System.Windows.Controls } EnterCounter(Counters.__MeasureChild); - Control child = InternalChildren[cell]; + IControl child = InternalChildren[cell]; if (child != null) { Size childConstraint = new Size(cellMeasureWidth, cellMeasureHeight); @@ -2071,7 +1873,7 @@ namespace System.Windows.Controls if (useLayoutRounding) { roundingErrors[i] = definitions[i].SizeCache; - definitions[i].SizeCache = Control.RoundLayoutValue(definitions[i].SizeCache, dpi); + definitions[i].SizeCache = IControl.RoundLayoutValue(definitions[i].SizeCache, dpi); } } definitionIndices[starDefinitionsCount++] = i; @@ -2110,7 +1912,7 @@ namespace System.Windows.Controls if (useLayoutRounding) { roundingErrors[i] = definitions[i].SizeCache; - definitions[i].SizeCache = Control.RoundLayoutValue(definitions[i].SizeCache, dpi); + definitions[i].SizeCache = IControl.RoundLayoutValue(definitions[i].SizeCache, dpi); } allPreferredArrangeSize += definitions[i].SizeCache; @@ -2161,7 +1963,7 @@ namespace System.Windows.Controls if (useLayoutRounding) { roundingErrors[definitionIndices[i]] = definitions[definitionIndices[i]].SizeCache; - definitions[definitionIndices[i]].SizeCache = Control.RoundLayoutValue(definitions[definitionIndices[i]].SizeCache, dpi); + definitions[definitionIndices[i]].SizeCache = IControl.RoundLayoutValue(definitions[definitionIndices[i]].SizeCache, dpi); } allPreferredArrangeSize += definitions[definitionIndices[i]].SizeCache; @@ -2186,7 +1988,7 @@ namespace System.Windows.Controls if (useLayoutRounding) { roundingErrors[definitionIndex] = final; - final = Control.RoundLayoutValue(finalOld, dpi); + final = IControl.RoundLayoutValue(finalOld, dpi); final = Math.Max(final, definitions[definitionIndex].MinSizeForArrange); final = Math.Min(final, definitions[definitionIndex].SizeCache); } @@ -2213,7 +2015,7 @@ namespace System.Windows.Controls RoundingErrorIndexComparer roundingErrorIndexComparer = new RoundingErrorIndexComparer(roundingErrors); Array.Sort(definitionIndices, 0, definitions.Length, roundingErrorIndexComparer); double adjustedSize = allPreferredArrangeSize; - double dpiIncrement = Control.RoundLayoutValue(1.0, dpi); + double dpiIncrement = IControl.RoundLayoutValue(1.0, dpi); if (allPreferredArrangeSize > finalSize) { @@ -2612,7 +2414,7 @@ namespace System.Windows.Controls for (int i = 0; i < definitions.Length; ++i) { DefinitionBase def = definitions[i]; - double roundedSize = Control.RoundLayoutValue(def.SizeCache, dpi); + double roundedSize = IControl.RoundLayoutValue(def.SizeCache, dpi); roundingErrors[i] = (roundedSize - def.SizeCache); def.SizeCache = roundedSize; roundedTakenSize += roundedSize; @@ -2826,29 +2628,6 @@ namespace System.Windows.Controls } } - /// - /// Returns true if ColumnDefinitions collection is not empty - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public bool ShouldSerializeColumnDefinitions() - { - ExtendedData extData = ExtData; - return (extData != null - && extData.ColumnDefinitions != null - && extData.ColumnDefinitions.Count > 0); - } - - /// - /// Returns true if RowDefinitions collection is not empty - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public bool ShouldSerializeRowDefinitions() - { - ExtendedData extData = ExtData; - return (extData != null - && extData.RowDefinitions != null - && extData.RowDefinitions.Count > 0); - } /// /// Synchronized ShowGridLines property with the state of the grid's visual collection @@ -2991,16 +2770,6 @@ namespace System.Windows.Controls return (result != 2); } - #endregion Private Methods - - //------------------------------------------------------ - // - // Private Properties - // - //------------------------------------------------------ - - #region Private Properties - /// /// Private version returning array of column definitions. /// @@ -4036,27 +3805,6 @@ namespace System.Windows.Controls return (false); } - public Object Current - { - get - { - if (_currentEnumerator == -1) - { -#pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception - throw new InvalidOperationException(SR.Get(SRID.EnumeratorNotStarted)); - } - if (_currentEnumerator >= 3) - { -#pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception - throw new InvalidOperationException(SR.Get(SRID.EnumeratorReachedEnd)); - } - - // assert below is not true anymore since ControlCollection allowes for null Children - //Debug.Assert(_currentChild != null); - return (_currentChild); - } - } - public void Reset() { _currentEnumerator = -1; @@ -4070,7 +3818,7 @@ namespace System.Windows.Controls private Object _currentChild; private ColumnDefinitionCollection.Enumerator _enumerator0; private RowDefinitionCollection.Enumerator _enumerator1; - private ControlCollection _enumerator2Collection; + private Controls _enumerator2Collection; private int _enumerator2Index; private int _enumerator2Count; } @@ -4157,7 +3905,5 @@ namespace System.Windows.Controls private static readonly Pen s_evenDashPen; // second pen to draw dash private static readonly Point c_zeroPoint = new Point(0, 0); } - - #endregion Private Structures Classes } } \ No newline at end of file