WPF Grid 中子控件之间的间距

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/895909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:28:00  来源:igfitidea点击:

Spacing between child controls in WPF Grid

wpflayoutgrid

提问by Grokys

I have a set of Key/Value pairs I want to display on a WPF Window. I'm using a grid to lay them out like so:

我有一组要在 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>

However when I display this, the TextBoxes are squashed up with their top and bottom borders touching the TextBox above/below. What is the best way to add vertical space to the rows in this layout?

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

回答by Matt Hamilton

Easiest way is to set a margin on the individual controls. Setting it on the TextBoxes should be enough, because once they're spaced out the Labels will set vertically in the center of each row and have plenty of space anyway.

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

You can set it once using a style:

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

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

    ...
</Grid>

This will add a 4-pixel margin to the bottom of any TextBox inside your grid.

这将在网格内的任何文本框的底部添加一个 4 像素的边距。

回答by Elad Katz

Another nice approach can be seen here.

另一个不错的方法可以在这里看到。

You create class for setting Marginproperty:

您创建用于设置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);
    }
}

Now you have attached property behavior, so that syntax like this would work:

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

<StackPanel local:MarginSetter.Margin="5">
   <TextBox Text="hello" />
   <Button Content="hello" />
   <Button Content="hello" />
</StackPanel>

This is the easiest & fastest way to set Marginto several children of a panel, even if they are not of the same type. (I.e. Buttons, TextBoxes, ComboBoxes, etc.)

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

回答by Norman

What about setting TextBox's VerticalAlignment to Center?

将 TextBox 的 VerticalAlignment 设置为 Center 怎么样?

<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}" VerticalAlignment="Center"/>

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