我已经为这个问题挠头好几天了。我正在尝试创建一个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只是我喜欢的TextBlock
和TextBox
样式:
<TextBlock Text="{Binding Label}"/>
<TextBlock Text="{Binding Text}"/>
据我所知,这有几个问题:
1.-为了使元素受到网格布局的影响,它必须是该网格的直接子元素。
2.-行数是任意的。在Grid
中,您需要指定每一行的定义。
如果我能以某种方式让Grid
的布局不仅影响直系子代,而且影响嵌套子代,我想我可以做到这一点。如果你能想到的话,我也愿意用一种不同的方法来解决这个问题。
预期的最终行为是StackPanel
和Grid
的混合,即:
~可以添加任意数量的元素,而无需定义行(只需堆叠它们(。
~容器分为两列,第一列为包含的最大元素的大小(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
可以是任何类型的容器(例如StackPanel
、UniformGrid
等(。
在上文中,每个RowControl
的Grid
的第一列将是均匀的(它们都将增长以容纳最大的Label
(。根据需要,您可能还需要在第二列上设置SharedSizeGroup
(设置为不同的值,类似于"RowText"(。