如何将网格布局应用于嵌套的子元素



我已经为这个问题挠头好几天了。我正在尝试创建一个UserControl,它将允许我简化创建I/O表单的过程。在许多形式中,我需要这样一个结构的东西:

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto">
<ColumnDefinition Width="*">
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition>
<RowDefinition>
<RowDefinition>          
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="..."/>
<TextBox Grid.Column="1" Grid.Row="0" Text="..."/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="..."/>
<TextBox Grid.Column="1" Grid.Row="1" Text="..."/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="..."/>
<TextBox Grid.Column="1" Grid.Row="2" Text="..."/>
...
<Grid>

我想写的是这样的东西:

<mycontrols:ContainerControl>
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
</mycontrols:ContainerControl>

RowControl的XAML只是我喜欢的TextBlockTextBox样式:

<TextBlock Text="{Binding Label}"/>
<TextBlock Text="{Binding Text}"/>

据我所知,这有几个问题:

1.-为了使元素受到网格布局的影响,它必须是该网格的直接子元素。

2.-行数是任意的。在Grid中,您需要指定每一行的定义。

如果我能以某种方式让Grid的布局不仅影响直系子代,而且影响嵌套子代,我想我可以做到这一点。如果你能想到的话,我也愿意用一种不同的方法来解决这个问题。

预期的最终行为是StackPanelGrid的混合,即:

~可以添加任意数量的元素,而无需定义行(只需堆叠它们(。

~容器分为两列,第一列为包含的最大元素的大小(auto(,第二列为可用宽度的剩余部分(*(。

欢迎所有帮助!提前感谢:(

您可能能够利用ColumnDefinition.SharedSizeGroup和附加的Grid.IsSharedSizeScope属性。试试这样的东西:

<UserControl x:Class="CSharpTest.RowControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="RowLabel"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Label}"/>
<TextBlock Text="{Binding Text}" Grid.Column="1"/>
</Grid>
</UserControl>

然后使用它:

<mycontrols:ContainerControl Grid.IsSharedSizeScope="True">
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
<mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
</mycontrols:ContainerControl>

mycontrols:ContainerControl可以是任何类型的容器(例如StackPanelUniformGrid等(。

在上文中,每个RowControlGrid的第一列将是均匀的(它们都将增长以容纳最大的Label(。根据需要,您可能还需要在第二列上设置SharedSizeGroup(设置为不同的值,类似于"RowText"(。

最新更新