Files
ShrlAlgoToolkit/Melskin/Layout/Grid.cs
2026-02-17 22:17:13 +08:00

795 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.ComponentModel;
using Melskin.Extensions;
namespace Melskin.Layout;
/// <summary>
/// Grid 类继承自 Grid提供自动布局功能。它允许子元素根据设定的列宽、对齐方式等属性自动排列。
/// 该类扩展了标准 Grid 的功能,添加了如自动索引和自定义列宽覆盖等特性,以简化复杂布局的创建。
/// </summary>
/// <remarks>
/// 通过使用依赖属性来控制子元素的水平和垂直对齐方式、边距以及整个网格的列宽和方向,
/// Grid 提供了一种灵活的方式来管理和调整用户界面中的布局结构。
/// 注意整个XAML文档控件的顺序使用Grid.Row和Grid.Column应逐行添加控件对于嵌套的AutoGrid其ChildMarginHorizonAlignmentVerticalAlignment会继承
/// </remarks>
public class Grid : System.Windows.Controls.Grid
{
/// <summary>
/// 获取或设置是否自动索引。
/// </summary>
/// <value>布尔值,表示是否启用自动索引。</value>
public static readonly DependencyProperty AutoIndexProperty = DependencyProperty.RegisterAttached(
"AutoIndex",
typeof(bool),
typeof(Grid),
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsParentMeasure));
/// <summary>
/// 获取或设置所有子控件的水平对齐方式。
/// </summary>
/// <value>一个可为空的 HorizontalAlignment 值,表示子控件的水平对齐方式。</value>
public static readonly DependencyProperty ChildHorizontalAlignmentProperty = DependencyProperty.Register(
nameof(ChildHorizontalAlignment),
typeof(HorizontalAlignment?),
typeof(Grid),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnChildHorizontalAlignmentChanged));
/// <summary>
/// 获取或设置子控件的边距。
/// </summary>
/// <value>表示子控件边距的 Thickness? 类型值。</value>
public static readonly DependencyProperty ChildMarginProperty = DependencyProperty.Register(
nameof(ChildMargin),
typeof(Thickness?),
typeof(Grid),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnChildMarginChanged));
/// <summary>
/// 获取或设置所有子控件的默认垂直对齐方式。
/// </summary>
/// <value>一个可为空的 VerticalAlignment 值,表示子控件的默认垂直对齐方式。</value>
public static readonly DependencyProperty ChildVerticalAlignmentProperty = DependencyProperty.Register(
nameof(ChildVerticalAlignment),
typeof(VerticalAlignment?),
typeof(Grid),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnChildVerticalAlignmentChanged));
/// <summary>
///
/// </summary>
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register(
nameof(Columns),
typeof(string),
typeof(Grid),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnColumnsChanged));
/// <summary>
/// 获取或设置列宽覆盖值。
/// </summary>
/// <value>GridLength? 类型的值,表示列宽的覆盖值。如果未设置,则使用默认列宽。</value>
public static readonly DependencyProperty ColumnWidthOverrideProperty = DependencyProperty.RegisterAttached(
"ColumnWidthOverride",
typeof(GridLength?),
typeof(Grid),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.AffectsArrange |
FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
///
/// </summary>
public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register(
nameof(ColumnWidth),
typeof(GridLength),
typeof(Grid),
new FrameworkPropertyMetadata(
GridLength.Auto,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnFixedColumnWidthChanged));
/// <summary>
/// 获取或设置是否启用自动布局索引。
/// </summary>
/// <value>布尔值,表示是否启用自动布局索引功能。</value>
public static readonly DependencyProperty IsAutoIndexingProperty = DependencyProperty.Register(
nameof(IsAutoIndexing),
typeof(bool),
typeof(Grid),
new FrameworkPropertyMetadata(
true,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnPropertyChanged));
/// <summary>
/// 获取或设置布局的方向。
/// </summary>
/// <value>表示布局方向的枚举值,可以是水平或垂直。</value>
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
nameof(Orientation),
typeof(Orientation),
typeof(Grid),
new FrameworkPropertyMetadata(
Orientation.Horizontal,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnPropertyChanged));
// RowHeight 重载附加属性
/// <summary>
/// 获取或设置行高度的重载值。
/// </summary>
/// <value>GridLength? 类型,表示行的高度。如果设置为 null则使用默认行高。</value>
public static readonly DependencyProperty RowHeightOverrideProperty = DependencyProperty.RegisterAttached(
"RowHeightOverride",
typeof(GridLength?),
typeof(Grid),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.AffectsArrange |
FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
/// 获取或设置网格中所有行的预设高度。
/// </summary>
/// <value>GridLength 类型,表示行的高度。默认值为 GridLength.Auto。</value>
public static readonly DependencyProperty RowHeightProperty = DependencyProperty.Register(
nameof(RowHeight),
typeof(GridLength),
typeof(Grid),
new FrameworkPropertyMetadata(
GridLength.Auto,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnFixedRowHeightChanged));
/// <summary>
///
/// </summary>
public static readonly DependencyProperty RowsProperty = DependencyProperty.Register(
nameof(Rows),
typeof(string),
typeof(Grid),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
OnRowsChanged));
int rowOrColumnCount;
bool shouldReindex = true;
/// <summary>
/// 用于在WPF应用程序中创建和管理网格布局的类。该类扩展了System.Windows.Controls.Grid提供了额外的功能如自动索引、列宽覆盖以及子元素对齐方式和边距的设置。
/// </summary>
public Grid()
{
Loaded += Grid_Loaded; }
/// <summary>
/// 应用默认子边距和对齐等布局效果
/// </summary>
void ApplyChildDefaultLayout(UIElement child)
{
if (ChildMargin != null)
{
child.SetIfDefault(MarginProperty, ChildMargin.Value);
}
if (ChildHorizontalAlignment != null)
{
child.SetIfDefault(HorizontalAlignmentProperty, ChildHorizontalAlignment.Value);
}
if (ChildVerticalAlignment != null)
{
child.SetIfDefault(VerticalAlignmentProperty, ChildVerticalAlignment.Value);
}
}
/// <summary>
/// 应用子边距和对齐等布局效果
/// </summary>
void ApplyChildLayout(UIElement child)
{
if (ChildMargin.HasValue)
{
child.SetValue(ChildMarginProperty, ChildMargin);
}
if (ChildHorizontalAlignment.HasValue)
{
child.SetValue(HorizontalAlignmentProperty, ChildHorizontalAlignment);
}
if (ChildVerticalAlignment.HasValue)
{
child.SetValue(VerticalAlignmentProperty, ChildVerticalAlignment);
}
}
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= Grid_Loaded;
if (Children.Count == 0)
{
return;
}
foreach (UIElement elem in Children)
{
ApplyChildLayout(elem);
}
}
/// <summary>
/// 改变【子水平对齐方式】时调用。
/// </summary>
private static void OnChildHorizontalAlignmentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Grid grid)
{
foreach (UIElement child in grid.Children)
{
child.SetValue(HorizontalAlignmentProperty, grid.ChildHorizontalAlignment ?? DependencyProperty.UnsetValue);
}
}
}
/// <summary>
/// 【子布局更改】时调用。
/// </summary>
private static void OnChildMarginChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Grid grid)
{
foreach (UIElement child in grid.Children)
{
child.SetValue(MarginProperty, grid.ChildMargin ?? DependencyProperty.UnsetValue);
}
}
}
/// <summary>
/// 改变【子垂直排列方式】时调用。
/// </summary>
private static void OnChildVerticalAlignmentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Grid grid)
{
foreach (UIElement child in grid.Children)
{
child.SetValue(VerticalAlignmentProperty, grid.ChildVerticalAlignment ?? DependencyProperty.UnsetValue);
}
}
}
/// <summary>
/// 处理列更改事件
/// </summary>
private static void OnColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((string)e.NewValue == string.Empty)
{
return;
}
if (d is Grid grid)
{
grid.ColumnDefinitions.Clear();
var defs = Parse((string)e.NewValue);
foreach (var def in defs)
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = def });
}
}
/// <summary>
/// 处理固定列宽更改事件
/// </summary>
private static void OnFixedColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Grid grid)
{
// 如果缺少,添加默认列
if (grid.ColumnDefinitions.Count == 0)
grid.ColumnDefinitions.Add(new ColumnDefinition());
// 将所有现有列设置为该宽度
foreach (var t in grid.ColumnDefinitions)
t.Width = (GridLength)e.NewValue;
}
}
/// <summary>
/// 处理固定行高更改事件
/// </summary>
private static void OnFixedRowHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Grid grid)
{
// 如果缺失,则添加默认行
if (grid.RowDefinitions.Count == 0)
grid.RowDefinitions.Add(new RowDefinition());
// 将所有现有行设置为该高度
foreach (var t in grid.RowDefinitions)
t.Height = (GridLength)e.NewValue;
}
}
/// <summary>
/// 处理重绘属性更改事件
/// </summary>
static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ ((Grid)d).shouldReindex = true; }
/// <summary>
/// 处理行修改事件
/// </summary>
private static void OnRowsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((string)e.NewValue == string.Empty)
{
return;
}
if (d is Grid grid)
{
grid.RowDefinitions.Clear();
var defs = Parse((string)e.NewValue);
foreach (var def in defs)
grid.RowDefinitions.Add(new RowDefinition() { Height = def });
}
}
///// <summary>
///// 将某一数值限制在最大值。
///// </summary>
//int Clamp(int value, int max)
//{
// return value > max ? max : value;
//}
/// <summary>
/// 从逗号分隔符文本中解析网格长度数组
/// </summary>
private static GridLength[] Parse(string text)
{
var tokens = text.Split(',');
var definitions = new GridLength[tokens.Length];
for (var i = 0; i < tokens.Length; i++)
{
var str = tokens[i];
double value;
// 占比
if (str.Contains('*'))
{
if (!double.TryParse(str.Replace("*", string.Empty), out value))
value = 1.0;
definitions[i] = new GridLength(value, GridUnitType.Star);
continue;
}
// 像素
if (double.TryParse(str, out value))
{
definitions[i] = new GridLength(value);
continue;
}
if (str.Equals("auto", StringComparison.CurrentCultureIgnoreCase))
{
definitions[i] = GridLength.Auto;
}
//definitions[i] = GridLength.Auto;
}
return definitions;
}
private void PerformLayout()
{
var isVertical = Orientation == Orientation.Vertical;
if (shouldReindex ||
IsAutoIndexing &&
(isVertical &&
rowOrColumnCount != ColumnDefinitions.Count ||
!isVertical &&
rowOrColumnCount != RowDefinitions.Count))
{
shouldReindex = false;
if (IsAutoIndexing)
{
rowOrColumnCount = ColumnDefinitions.Count != 0 ? ColumnDefinitions.Count : RowDefinitions.Count;
if (rowOrColumnCount == 0)
rowOrColumnCount = 1;
var cellCount = 0;
foreach (UIElement child in Children)
{
if (GetAutoIndex(child) == false)
{
continue;
}
cellCount += ColumnDefinitions.Count != 0 ? GetColumnSpan(child) : GetRowSpan(child);
}
// 更新行/列数
if (ColumnDefinitions.Count != 0)
{
var newRowCount = (int)Math.Ceiling(cellCount / (double)rowOrColumnCount);
while (RowDefinitions.Count < newRowCount)
{
var rowDefinition = new RowDefinition { Height = RowHeight };
RowDefinitions.Add(rowDefinition);
}
if (RowDefinitions.Count > newRowCount)
{
RowDefinitions.RemoveRange(newRowCount, RowDefinitions.Count - newRowCount);
}
}
else // 已定义的行
{
var newColumnCount = (int)Math.Ceiling(cellCount / (double)rowOrColumnCount);
while (ColumnDefinitions.Count < newColumnCount)
{
var columnDefinition = new ColumnDefinition { Width = ColumnWidth };
ColumnDefinitions.Add(columnDefinition);
}
if (ColumnDefinitions.Count > newColumnCount)
{
ColumnDefinitions.RemoveRange(newColumnCount, ColumnDefinitions.Count - newColumnCount);
}
}
}
// 更新子项索引
var cellPosition = 0;
var cellsToSkip = new Queue<int>();
foreach (UIElement child in Children)
{
if (IsAutoIndexing && GetAutoIndex(child))
{
if (cellsToSkip.Any() && cellsToSkip.Peek() == cellPosition)
{
cellsToSkip.Dequeue();
cellPosition += 1;
}
if (!isVertical) // 水平(默认)
{
var rowIndex = cellPosition / ColumnDefinitions.Count;
SetRow(child, rowIndex);
var columnIndex = cellPosition % ColumnDefinitions.Count;
SetColumn(child, columnIndex);
var rowSpan = GetRowSpan(child);
if (rowSpan > 1)
{
Enumerable
.Range(1, rowSpan)
.ToList()
.ForEach(x => cellsToSkip.Enqueue(cellPosition + ColumnDefinitions.Count * x));
}
var overrideRowHeight = GetRowHeightOverride(child);
if (overrideRowHeight != null)
{
RowDefinitions[rowIndex].Height = overrideRowHeight.Value;
}
var overrideColumnWidth = GetColumnWidthOverride(child);
if (overrideColumnWidth != null)
{
ColumnDefinitions[columnIndex].Width = overrideColumnWidth.Value;
}
cellPosition += GetColumnSpan(child);
}
else
{
var rowIndex = cellPosition % RowDefinitions.Count;
SetRow(child, rowIndex);
var columnIndex = cellPosition / RowDefinitions.Count;
SetColumn(child, columnIndex);
var columnSpan = GetColumnSpan(child);
if (columnSpan > 1)
{
Enumerable
.Range(1, columnSpan)
.ToList()
.ForEach(x => cellsToSkip.Enqueue(cellPosition + RowDefinitions.Count * x));
}
var overrideRowHeight = GetRowHeightOverride(child);
if (overrideRowHeight != null)
{
RowDefinitions[rowIndex].Height = overrideRowHeight.Value;
}
var overrideColumnWidth = GetColumnWidthOverride(child);
if (overrideColumnWidth != null)
{
ColumnDefinitions[columnIndex].Width = overrideColumnWidth.Value;
}
cellPosition += GetRowSpan(child);
}
}
// 设置默认页边距和对齐方式
ApplyChildDefaultLayout(child);
}
}
}
/// <summary>
/// 测量 <see cref="T:System.Windows.Controls.Grid"/> 的子网格,以便在 <see cref="M:System.Windows.Controls.Grid.ArrangeOverride"/> 传递期间整理它们。
/// </summary>
/// <param name="constraint">表示不应超过的上限大小。</param>
/// <returns>
/// <see cref="Size"/> 表示安排子内容所需的大小。
/// </returns>
protected override Size MeasureOverride(Size constraint)
{
PerformLayout();
return base.MeasureOverride(constraint);
}
/// <summary>
/// 当 <see cref="System.Windows.Controls.Grid"/> 元素的可视化子元素发生变化时调用。 <remarks>用于标记网格已更改子项。</remarks>
/// </summary>
/// <param name="visualAdded">标识添加的Visual子项。</param>
/// <param name="visualRemoved">标识移除的Visual子项。</param>
protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
{
shouldReindex = true;
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
}
/// <summary>
/// 获取指定元素的自动索引状态。
/// </summary>
/// <param name="element">要获取自动索引状态的依赖对象。</param>
/// <returns>如果元素启用了自动索引则返回true否则返回false。</returns>
public static bool GetAutoIndex(DependencyObject element)
{
return (bool)element.GetValue(AutoIndexProperty); }
/// <summary>
/// 获取指定元素的列宽覆盖值。
/// </summary>
/// <param name="element">要获取列宽覆盖值的依赖对象。</param>
/// <returns>如果为该元素设置了列宽覆盖则返回其GridLength值否则返回null。</returns>
public static GridLength? GetColumnWidthOverride(DependencyObject element)
{
return (GridLength?)element.GetValue(ColumnWidthOverrideProperty); }
/// <summary>
/// 获取指定元素的行高覆盖值。
/// </summary>
/// <param name="element">要获取行高覆盖值的依赖对象。</param>
/// <returns>返回一个GridLength?类型的值表示指定元素的行高覆盖。如果未设置则返回null。</returns>
public static GridLength? GetRowHeightOverride(DependencyObject element)
{
return (GridLength?)element.GetValue(RowHeightOverrideProperty); }
/// <summary>
/// 设置指定元素的自动索引属性。
/// </summary>
/// <param name="element">要设置自动索引属性的依赖对象。</param>
/// <param name="value">一个布尔值,表示是否启用自动索引功能。</param>
public static void SetAutoIndex(DependencyObject element, bool value)
{
element.SetValue(AutoIndexProperty, value); }
/// <summary>
/// 设置指定元素的列宽覆盖值。
/// </summary>
/// <param name="element">要设置列宽覆盖值的依赖对象。</param>
/// <param name="value">新的列宽覆盖值类型为GridLength?允许设置为null以清除覆盖。</param>
public static void SetColumnWidthOverride(DependencyObject element, GridLength? value)
{
element.SetValue(ColumnWidthOverrideProperty, value); }
/// <summary>
/// 设置指定元素的行高覆盖值。这允许开发者自定义网格中特定行的高度。
/// </summary>
/// <param name="element">要设置行高覆盖值的UI元素。</param>
/// <param name="value">新的行高值,可以是绝对值、自动或星形尺寸。</param>
public static void SetRowHeightOverride(DependencyObject element, GridLength? value)
{
element.SetValue(RowHeightOverrideProperty, value);
}
/// <summary>
/// 获取或设置子项水平对齐方式。
/// </summary>
/// <value>子项水平对齐。</value>
[Category("Layout"), Description("预设所有子控件的水平对齐方式")]
public HorizontalAlignment? ChildHorizontalAlignment
{
get => (HorizontalAlignment?)GetValue(ChildHorizontalAlignmentProperty);
set => SetValue(ChildHorizontalAlignmentProperty, value);
}
///// <summary>
///// 行数
///// </summary>
//public int RowCount
//{
// get { return (int)GetValue(RowCountProperty); }
// set { SetValue(RowCountProperty, value); }
//}
//// Using a DependencyProperty as the backing store for RowCount. This enables animation, styling, binding, etc...
//public static readonly DependencyProperty RowCountProperty = DependencyProperty.Register(
// nameof(RowCount),
// typeof(int),
// typeof(Grid),
// new PropertyMetadata(1, new PropertyChangedCallback(OnRowCountChanged))
//);
///// <summary>
///// 处理行数修改事件
///// </summary>
//private static void OnRowCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//{
// if (d is Grid grid)
// {
// if ((int)e.NewValue < 0 || grid.Rows != string.Empty)
// {
// return;
// }
// // 查找现有行以获取高度
// var height = GridLength.Auto;
// //var height = new GridLength(1, GridUnitType.Star);
// if (grid.RowDefinitions.Count > 0)
// height = grid.RowDefinitions[0].Height;
// // 清理和重建
// grid.RowDefinitions.Clear();
// for (var i = 0; i < (int)e.NewValue; i++)
// grid.RowDefinitions.Add(new RowDefinition() { Height = height });
// }
//}
///// <summary>
///// 列数量
///// </summary>
//public int ColumnCount
//{
// get { return (int)GetValue(ColumnCountProperty); }
// set { SetValue(ColumnCountProperty, value); }
//}
//// Using a DependencyProperty as the backing store for RowCount. This enables animation, styling, binding, etc...
//public static readonly DependencyProperty ColumnCountProperty = DependencyProperty.Register(
// nameof(ColumnCount),
// typeof(int),
// typeof(Grid),
// new PropertyMetadata(1, new PropertyChangedCallback(OnColumnCountChanged))
//);
///// <summary>
///// 处理列数更改事件
///// </summary>
//private static void OnColumnCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//{
// if (d is Grid grid)
// {
// if ((int)e.NewValue < 0 || grid.Columns != string.Empty)
// {
// return;
// }
// // 查找高度的现有列定义
// var width = GridLength.Auto;
// //均分
// //var width = new GridLength(1, GridUnitType.Star);
// if (grid.ColumnDefinitions.Count > 0)
// width = grid.ColumnDefinitions[0].Width;
// // 清理和重建
// grid.ColumnDefinitions.Clear();
// for (var i = 0; i < (int)e.NewValue; i++)
// grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = width });
// }
//}
/// <summary>
/// 获取或设置子项边距。
/// </summary>
/// <value>子项边距</value>
[Category("Layout"),
Description("预设所有子控件的边距")]
public Thickness? ChildMargin
{
get => (Thickness?)GetValue(ChildMarginProperty);
set => SetValue(ChildMarginProperty, value);
}
/// <summary>
/// 获取或设置子项垂直对齐方式。
/// </summary>
/// <value>子项垂直排列。</value>
[Category("Layout"), Description("预设所有子控件的垂直对齐方式")]
public VerticalAlignment? ChildVerticalAlignment
{
get => (VerticalAlignment?)GetValue(ChildVerticalAlignmentProperty);
set => SetValue(ChildVerticalAlignmentProperty, value);
}
/// <summary>
/// 获取或设置列优先级高于ColumnCount
/// </summary>
[Category("Layout"), Description("使用逗号分隔的网格长度符号定义所有列")]
public string Columns
{
get => (string)GetValue(ColumnsProperty);
set => SetValue(ColumnsProperty, value);
}
/// <summary>
/// 获取或设置固定列宽,默认自动
/// </summary>
[Category("Layout"), Description("预设使用 ColumnCount 属性设置的所有列的宽度")]
public GridLength ColumnWidth
{
get => (GridLength)GetValue(ColumnWidthProperty);
set => SetValue(ColumnWidthProperty, value);
}
/// <summary>
/// 获取或设置表示是否自动索引子项的值。 <remarks> 默认值为<c>true</c>. 请注意,如果子项已有索引,将此属性设置为 <c>false</c> 将不会移除其索引。</remarks>
/// </summary>
[Category("Layout"), Description("设置为 false 则禁用自动布局功能")]
public bool IsAutoIndexing
{
get => (bool)GetValue(IsAutoIndexingProperty);
set => SetValue(IsAutoIndexingProperty, value);
}
/// <summary>
/// 获取或设置方向。 <remarks>默认值为垂直。</remarks>
/// </summary>
/// <value>定向。</value>
[Category("Layout"), Description("定义自动布局的方向性。列优先布局使用垂直方向,行优先布局使用水平方向。")]
public Orientation Orientation
{
get => (Orientation)GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
/// <summary>
/// 获取或设置固定行高
/// </summary>
[Category("Layout"), Description("预设使用行数属性设置的所有行的高度")]
public GridLength RowHeight
{
get => (GridLength)GetValue(RowHeightProperty);
set => SetValue(RowHeightProperty, value);
}
/// <summary>
/// 获取或设置行数,优先级高于RowCount
/// </summary>
[Category("Layout"), Description("使用逗号分隔的网格长度符号定义所有行")]
public string Rows
{
get => (string)GetValue(RowsProperty);
set => SetValue(RowsProperty, value);
}
}