WPF网格中子控件之间的间距

Gro*_*kys 56 wpf grid layout

我有一组要在WPF窗口上显示的键/值对.我正在使用网格将它们放置出来:

<Grid Margin="4">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Grid.Column="0">Code</Label>
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Code}"/>

    <Label Grid.Row="1" Grid.Column="0">Name</Label>
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

然而,当我显示它时,TextBoxes被压扁,它们的顶部和底部边框接触上方/下方的TextBox.在此布局中向行添加垂直空间的最佳方法是什么?

Mat*_*ton 83

最简单的方法是在各个控件上设置边距.在TextBox上设置它应该足够了,因为一旦它们间隔开,标签将垂直设置在每行的中心并且无论如何都有足够的空间.

您可以使用样式设置一次:

<Grid Margin="4">
    <Grid.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="0,0,0,4" />
        </Style>
    </Grid.Resources>

    ...
</Grid>
Run Code Online (Sandbox Code Playgroud)

这将在网格内任何TextBox的底部添加一个4像素的边距.


Ela*_*atz 49

这里可以看到另一种不错的方法.

您创建用于设置Margin属性的类:

public class MarginSetter
{
    public static Thickness GetMargin(DependencyObject obj) => (Thickness)obj.GetValue(MarginProperty);

    public static void SetMargin(DependencyObject obj, Thickness value) => obj.SetValue(MarginProperty, value);

    // Using a DependencyProperty as the backing store for Margin. This enables animation, styling, binding, etc…
    public static readonly DependencyProperty MarginProperty =
        DependencyProperty.RegisterAttached(nameof(FrameworkElement.Margin), typeof(Thickness),
            typeof(MarginSetter), new UIPropertyMetadata(new Thickness(), MarginChangedCallback));

    public static void MarginChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
    {
        // Make sure this is put on a panel
        var panel = sender as Panel;

        if (panel == null) return;

        panel.Loaded += Panel_Loaded;
    }

    private static void Panel_Loaded(object sender, EventArgs e)
    {
        var panel = sender as Panel;

        // Go over the children and set margin for them:
        foreach (FrameworkElement fe in panel.Children.OfType<FrameworkElement>())
            fe.Margin = GetMargin(panel);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你已经附加了属性行为,所以像这样的语法可以工作:

<StackPanel local:MarginSetter.Margin="5">
   <TextBox Text="hello" />
   <Button Content="hello" />
   <Button Content="hello" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

这是设置Margin为面板的多个子项的最简单,最快捷的方法,即使它们的类型不同.(即Button,TextBoxes,ComboBoxes等)

  • +1很棒.我将类名更改为LayoutSetter并添加了一些其他属性,如VerticalAlignment,以相同的方式传播它.我希望我可以简单地为FrameworkElement定义一个样式...... (4认同)