我正在寻找一种不那么繁琐的方法来布局键/值对(例如,标签说"名字"后跟带有名字的标签)。如果它只是一个简单的分组,我会把它扔进网格并完成。然而,布局2或3对,接着是一些类型的分组容器,有4或5对,后面是不同的分组容器等。
做这样的事情感觉非常麻烦:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Element ID:" HorizontalAlignment="Right" />
<Label Grid.Column="1" Grid.Row="0" Content="{Binding Path=ElementId}" HorizontalAlignment="Left" FontWeight="Bold" />
<Label Grid.Column="0" Grid.Row="1" Content="Element Description:" HorizontalAlignment="Right" />
<Label Grid.Column="1" Grid.Row="1" Content="{Binding Path=ElementDescription}" HorizontalAlignment="Left" FontWeight="Bold" />
</Grid>
只是渲染出来:
_______元素ID:ABC123
元素描述:Spiffy!
当你有几个这样的部分时,尤其如此。
UniformGrid不允许您修复一列,以便Label可以右对齐。我尝试了StackPanel和WrapPanel的组合,但最终会产生大量的开销和大量的边缘摆弄。
有更好的方法吗?
答案 0 :(得分:4)
据我所知,你应该可以做这样的事情,当你有很多这样的东西时非常方便;
<UniformGrid Columns="2">
<UniformGrid.Resources>
<!-- Set your properties once, in one place,
and control your children like a good parent. -->
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"/>
<!-- If you want to control your cell width so the descriptions doesn't
offset the size of the ID's you could just enable/edit these setters.
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="MaxWidth" Value="150"/>
-->
</Style>
</UniformGrid.Resources>
<Label Content="Element ID:"/>
<TextBlock Text="{Binding Path=ElementId}"/>
<Label Content="Element Description:"/>
<TextBlock Text="{Binding Path=ElementDescription}"/>
<!-- etc, etc, etc. -->
</UniformGrid>
PS - 避免使用Label
并使用TextBlock
,除非它真的有益,因为Label比TextBlock重。
希望这会有所帮助,欢呼。
答案 1 :(得分:3)
您可以将Autogrid用于xaml,如下所示:
<AutoGrid RowCount="2" RowHeight="35" Columns="100,auto">
<Label />
<TextBox />
<Label />
<TextBox />
</AutoGrid>
答案 2 :(得分:1)
您可以创建shared size group,它允许单独的Grid
中的多个列具有相同的大小。然后,您可以使用ItemsControl
附加属性设置为Grid.IsSharedSizeScope
的{{1}}来显示您的商品。它可能有点沉重,因为它为每一行创建了一个新的true
,但这是我能够获得的结果(full code here):
在我的视图模型中,我创建了一个基类Grid
和两个子类Row
和DividerRow
。主视图模型有KeyValueRow
行,填充方式如下:
ObservableCollection<Row>
XAML定义绑定到Rows的ItemsControl并将自己定义为共享大小范围:
public class ViewModel : BaseVM
{
ObservableCollection<Row> _rows = new ObservableCollection<Row> ();
public ObservableCollection<Row> Rows { get { return _rows; } }
public ViewModel()
{
_rows.Add (new DividerRow () { Title = "Fruit" });
_rows.Add (new KeyValueRow () { Key = "Apple", Value = "$1.01" });
_rows.Add (new KeyValueRow () { Key = "Apricot", Value = "$2.01" });
_rows.Add (new KeyValueRow () { Key = "Pineapple", Value = "$3.01" });
_rows.Add (new DividerRow () { Title = "Meat" });
_rows.Add (new KeyValueRow () { Key = "Bacon", Value = "$4.01" });
_rows.Add (new KeyValueRow () { Key = "Ground-Turkey", Value = "$5.01" });
_rows.Add (new KeyValueRow () { Key = "Sausage", Value = "$6.01" });
_rows.Add (new KeyValueRow () { Key = "Andmorereallytastystuff", Value = "$7.01" });
}
}
每个单独的行都是使用窗口资源字典中的无名,基于类型的<Canvas>
<ItemsControl ItemsSource="{Binding Rows}" Margin="50" Grid.IsSharedSizeScope="True" />
</Canvas>
来定义的。分隔线并不是非常相互影响的。它只是DataTemplate
:
TextBlock
使列具有相同宽度的有趣部分位于行的模板中,该列将列定义为<DataTemplate DataType="{x:Type l:DividerRow}">
<TextBlock HorizontalAlignment="Stretch"
TextAlignment="Center"
FontWeight="Bold"
Padding="5,5,5,0"
Margin="0,10,0,0"
Background="LightBlue"
Text="{Binding Title}" />
</DataTemplate>
的A和B.
SharedSizeGroup
请注意,如果<DataTemplate DataType="{x:Type l:KeyValueRow}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A" Width="Auto" />
<ColumnDefinition SharedSizeGroup="B" Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
HorizontalAlignment="Right"
Text="{Binding Key}" />
<TextBlock Grid.Column="1"
Margin="5,0,5,0"
FontWeight="Bold"
Text="{Binding Value}" />
</Grid>
</DataTemplate>
中没有Grid.IsSharedSizeScope
,则无法正常使用。希望有所帮助!很抱歉格式化详细,但我希望XAML与提供的示例图像相匹配。
答案 3 :(得分:0)
为每种标签类型创建一种样式,用于定义对齐和字体粗细。这样可以减少重复次数,并为您提供单点管理外观。
或者,在视图模型中将它们显示为字典,并使用带有模板的项控件来显示它们。