WPF:具有列/行边距/填充的网格?

Bra*_*ach 125 wpf grid margin padding

是否可以轻松地为WPF网格中的行或列指定边距和/或填充?

我当然可以添加额外的列来解决问题,但这似乎是填充/边距的工作(它将提供简单的XAML).有人从标准网格派生出来添加此功能吗?

Cha*_*lie 78

RowDefinitionColumnDefinition有型的ContentElement,而且Margin是严格意义上的FrameworkElement财产.所以对于你的问题,"这很容易",答案是肯定的.不,我没有看到任何展示这种功能的布局面板.

您可以按照建议添加额外的行或列.但是你也可以在Grid元素本身上设置边距,或者在内部设置任何内容,Grid这是你现在最好的解决方法.

  • OP 不会尝试在 RowDefinition 或 ColumnDefinition 上设置边距。他试图在网格的视觉子项上设置边距,这些子项派生自 FrameworkElement。 (3认同)

小智 42

使用Border单元格控件外部的控件并为其定义填充:

    <Grid>
        <Grid.Resources >
            <Style TargetType="Border" >
                <Setter Property="Padding" Value="5,5,5,5" />
            </Style>
        </Grid.Resources>

        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Border Grid.Row="0" Grid.Column="0">
            <YourGridControls/>
        </Border>
        <Border Grid.Row="1" Grid.Column="0">
            <YourGridControls/>
        </Border>

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


资源:

  • 链接页面现在有服务器错误. (2认同)
  • @RichardEverett检查返回机器:链接更新回答. (2认同)
  • 我最喜欢这个答案。它提供了原始问题的解决方案,而且很简单。谢谢! (2认同)
  • 这个简单又实用 (2认同)

小智 18

你可以使用这样的东西:

<Style TargetType="{x:Type DataGridCell}">
  <Setter Property="Padding" Value="4" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type DataGridCell}">
        <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
          <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
Run Code Online (Sandbox Code Playgroud)

或者,如果您不需要TemplateBindings:

<Style TargetType="{x:Type DataGridCell}">
   <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="{x:Type DataGridCell}">
              <Border Padding="4">
                  <ContentPresenter />
              </Border>
          </ControlTemplate>
      </Setter.Value>
  </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

  • 感谢JayGee,但是这个解决方案适用于DataGrid - 而不是标准的Grid控件. (25认同)

Tho*_*que 13

您可以编写自己的GridWithMargin类,继承Grid并覆盖ArrangeOverride应用边距的方法

  • 我不明白为什么人们会给您竖起大拇指,因为它远没有您在这里想到/描述的那么容易。只需尝试执行30分钟,您很快就会发现您的答案不适用。还考虑行和列的跨越 (10认同)

Jam*_*s M 6

以为我会添加我自己的解决方案,因为还没有人提到这一点。您可以使用样式声明来定位包含在网格中的控件,而不是设计基于Grid的UserControl。不必在每个元素上都定义填充,而是在所有元素上添加了填充/边距,这很麻烦且费力。例如,如果您的Grid除了TextBlocks之外什么都不包含,您可以执行以下操作:

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="10"/>
</Style>
Run Code Online (Sandbox Code Playgroud)

就像“单元格填充”一样。

  • @Maslow答案是绝对“是”,但您的措辞有些误导​​。没有“继承”属性的“继承”,这是“ ResourceDictionary”中的任何“ Style”都将应用于“ TargetType”的每个元素,在整个字典所有者的整个范围内***元件。因此,点滴是样式,而不是属性。 (2认同)

15e*_*153 6

这并不困难。我不能说在2009年问这个问题有多困难,但是那是那时。

请注意,如果在使用此解决方案时直接在网格的子级上直接设置边距,则该边距将显示在设计器中,但不会在运行时显示。

此属性可以应用于Grid,StackPanel,WrapPanel,UniformGrid或Panel的任何其他后代。它影响到直系孩子。假定孩子将要管理自己内容的布局。

PanelExt.cs

public static class PanelExt
{
    public static Thickness? GetChildMargin(Panel obj)
    {
        return (Thickness?)obj.GetValue(ChildMarginProperty);
    }

    public static void SetChildMargin(Panel obj, Thickness? value)
    {
        obj.SetValue(ChildMarginProperty, value);
    }

    /// <summary>
    /// Apply a fixed margin to all direct children of the Panel, overriding all other margins.
    /// Panel descendants include Grid, StackPanel, WrapPanel, and UniformGrid
    /// </summary>
    public static readonly DependencyProperty ChildMarginProperty =
        DependencyProperty.RegisterAttached("ChildMargin", typeof(Thickness?), typeof(PanelExt),
            new PropertyMetadata(null, ChildMargin_PropertyChanged));

    private static void ChildMargin_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var target = d as Panel;

        target.Loaded += (s, e2) => ApplyChildMargin(target, (Thickness?)e.NewValue);

        ApplyChildMargin(target, (Thickness?)e.NewValue);
    }

    public static void ApplyChildMargin(Panel panel, Thickness? margin)
    {
        int count = VisualTreeHelper.GetChildrenCount(panel);

        object value = margin.HasValue ? margin.Value : DependencyProperty.UnsetValue;

        for (var i = 0; i < count; ++i)
        {
            var child = VisualTreeHelper.GetChild(panel, i) as FrameworkElement;

            if (child != null)
            {
                child.SetValue(FrameworkElement.MarginProperty, value);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

演示:

MainWindow.xaml

<Grid
    local:PanelExt.ChildMargin="2"
    x:Name="MainGrid"
    >
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Rectangle Width="100" Height="40" Fill="Red" Grid.Row="0" Grid.Column="0" />
    <Rectangle Width="100" Height="40" Fill="Green" Grid.Row="1" Grid.Column="0" />
    <Rectangle Width="100" Height="40" Fill="Blue" Grid.Row="1" Grid.Column="1" />

    <Button Grid.Row="2" Grid.Column="0" Click="NoMarginClick">No Margin</Button>
    <Button Grid.Row="2" Grid.Column="1" Click="BigMarginClick">Big Margin</Button>
    <ComboBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void NoMarginClick(object sender, RoutedEventArgs e)
    {
        //  In real life, if we wanted to change PanelExt.ChildMargin at runtime, we 
        //  would prefer to bind it to something, probably a dependency property of 
        //  the view. But this will do for a demonstration. 
        PanelExt.SetChildMargin(MainGrid, null);
    }
    private void BigMarginClick(object sender, RoutedEventArgs e)
    {
        PanelExt.SetChildMargin(MainGrid, new Thickness(20));
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

  • @thesystem我认为有人为某事感到沮丧。没什么大不了的。但是也许其中有一个我错过的错误。它发生了。 (2认同)