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


Answers

RowDefinitionColumnDefinitionContentElement类型的, Margin是一个FrameworkElement属性。 所以对于你的问题, “这是否容易” ,答案是一个非常明确的答案。 不,我还没有看到任何展示这种功能的布局面板。

您可以按照您的建议添加额外的行或列。 但是你也可以在Grid元素上设置边距,或者在Grid设置边距,这是目前最好的解决方法。

Question

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

我当然可以添加额外的列来将空间分开,但这看起来像是填充/边距的工作(它会给出简单的XAML)。 是否有人从标准Grid派生出来添加这个功能?




我最近在开发一些软件时遇到了这个问题,并且问我为什么要问这个问题? 他们为什么这样做?答案就在我面前。 一行数据是一个对象,所以如果我们保持对象的方向,那么特定行的设计应该是分开的(假设你将来需要重新使用行显示)。 所以我开始为大多数数据显示使用数据绑定堆栈面板和自定义控件。 列表偶尔会出现,但大多数网格仅用于主页面组织(标题,菜单区域,内容区域,其他区域)。 您的自定义对象可以轻松地管理堆栈面板或网格中每行的任何间距要求(单个网格单元格可以包含整个行对象,还可以正确反应方向变化,展开/折叠等等。

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

  <custom:MyRowObject Style="YourStyleHereOrGeneralSetter" Grid.Row="0" />
  <custom:MyRowObject Style="YourStyleHere" Grid.Row="1" />
</Grid>

要么

<StackPanel>
  <custom:MyRowObject Style="YourStyleHere" Grid.Row="0" />
  <custom:MyRowObject Style="YourStyleHere" Grid.Row="1" />
</StackPanel>

如果您使用数据绑定,您的自定义控件也将继承DataContext ...这是我个人最喜欢的方法。




有时候简单的方法是最好的。 只需用空格填充你的字符串。 如果只有几个文本框等,这是迄今为止最简单的方法。

您也可以简单地插入固定大小的空白列/行。 非常简单,你可以很容易地改变它。




如前所述创建一个GridWithMargins类。 这是我的工作代码示例

public class GridWithMargins : Grid
{
    public Thickness RowMargin { get; set; } = new Thickness(10, 10, 10, 10);
    protected override Size ArrangeOverride(Size arrangeSize)
    {
        var basesize = base.ArrangeOverride(arrangeSize);

        foreach (UIElement child in InternalChildren)
        {
            var pos = GetPosition(child);
            pos.X += RowMargin.Left;
            pos.Y += RowMargin.Top;

            var actual = child.RenderSize;
            actual.Width -= (RowMargin.Left + RowMargin.Right);
            actual.Height -= (RowMargin.Top + RowMargin.Bottom);
            var rec = new Rect(pos, actual);
            child.Arrange(rec);
        }
        return arrangeSize;
    }

    private Point GetPosition(Visual element)
    {
        var posTransForm = element.TransformToAncestor(this);
        var areaTransForm = posTransForm.Transform(new Point(0, 0));
        return areaTransForm;
    }
}



<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:GridWithMargins ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Rectangle Fill="Red" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            <Rectangle Fill="Green" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            <Rectangle Fill="Blue" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
        </local:GridWithMargins>
    </Grid>
</Window>



在uwp(Windows10FallCreatorsUpdate版本及以上)

<Grid RowSpacing="3" ColumnSpacing="3">



你可以使用这样的东西:

<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>

或者如果你不需要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>



Related