我有 15-20 行,其中一些是不同的,但大多数是相似的:
<RowDefinition Height="Auto" />
而且我想避免代码重复,因为它大约有 10 行,一一对应。怎么做到呢?
它可以在没有 XAML 的代码中完成,但我认为解决这个问题的方法是错误的。
我认为不可能以某种方式简写网格行的声明,尤其是当并非所有网格行的 Height 属性都设置为“Auto”时。您可以尝试使用附加的依赖属性,如此处所示。
请注意,此示例指定了网格行数,您可以看到它以编程方式设置每行的 Height 属性。您可能必须以更复杂的方式决定为每一行分配什么高度。尽管这种解决方案在 XAML 中可能被证明更美观,但实现起来可能更复杂,并且您可能很难为每一行分配正确的高度。就个人而言,只声明每一行似乎更容易,因为 Visual Studio 将允许折叠标签和一个漂亮、清晰的方面。
我希望这有帮助!
我之前通过编写一个类来解决这个问题,该类提供一个附加属性来根据一个简单的逗号分隔列表自动定义行和列。您基本上需要做的是创建一个附加属性(我调用它AutoRows
并为属性更改的元数据定义一个方法。该方法解析值并简单地创建新RowDefinition
元素。
我使用了一个简单的语法,其中逗号分隔列表中的每个值都等于一行。所以20,20,20
会创建 3 行的高度20
。为了允许具有高度的行auto
并节省空间,我添加了一种新格式来在一个块中定义多个自动行。例如20,~5,20
定义一个带有 height 的行20
,然后是 5 个自动行,最后是另一个带有 height 的行20
。
我的变更处理程序基本上是这样做的:
public static void AutoRowsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
RowDefinitionCollection rows = ((Grid)obj).RowDefinitions;
rows.Clear();
foreach (string segment in ((string)e.NewValue).Split(','))
{
if (segment.StartsWith("~"))
{
int count;
if (!int.TryParse(segment.Substring(1), out count))
count = 1;
for (int i = 0; i < count; i++)
rows.Add(new RowDefinition() { Height = GridLength.Auto });
}
else
{
GridLengthConverter converter = new GridLengthConverter();
rows.Add(new RowDefinition() { Height = (GridLength)converter.ConvertFromString(segment) });
}
}
}
我遗漏了几行以确保它被正确解析并且没有任何错误。如您所见,我使用GridLengthConverter
使每个非自动值都接受法线RowDefinition
支持的任何值。因此,您可以通过逗号轻松连接所有行高,并将其用作附加属性的值。