WPF: ¿Cuadrícula con margen de columna / fila / relleno?


¿Es fácilmente posible especificar un margen y / o relleno para filas o columnas en una cuadrícula WPF?

Por supuesto, podría agregar columnas adicionales para espaciar las cosas, pero esto parece un trabajo para el relleno/márgenes (dará mucho XAML más simple). ¿Alguien ha derivado de la Cuadrícula estándar para agregar esta funcionalidad?

Author: Dave Clemmer, 2009-08-24

13 answers

Puede escribir su propia clase GridWithMargin, heredada de Grid, y anular el método ArrangeOverride para aplicar los márgenes

 15
Author: Thomas Levesque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-28 15:50:18

RowDefinition y ColumnDefinition son de tipo ContentElement, y Margin es estrictamente un FrameworkElement propiedad. Así que a tu pregunta, "¿es fácilmente posible" la respuesta es un no definitivo. Y no, no he visto ningún panel de diseño que demuestre este tipo de funcionalidad.

Puede agregar filas o columnas adicionales como lo sugirió. Pero también puede establecer márgenes en un elemento Grid en sí, o cualquier cosa que vaya dentro de un Grid, por lo que es su mejor solución por ahora.

 72
Author: Charlie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 17:51:25

Use un control Border fuera del control de celda y defina el relleno para eso:

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


Fuente:

 24
Author: samad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-24 23:40:25

Podrías usar algo como esto:

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

O si no necesita los 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>
 19
Author: JayGee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-08 15:18:15

Pensé en agregar mi propia solución porque nadie mencionó esto todavía. En lugar de diseñar un UserControl basado en Grid, puede dirigirse a los controles contenidos en grid con una declaración de estilo. Se encarga de agregar relleno / margen a todos los elementos sin tener que definir para cada uno, lo cual es engorroso y laborioso.Por ejemplo, si su Cuadrícula no contiene nada más que bloques de texto, puede hacer esto:

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="10"/>
</Style>

Que es como el equivalente de "relleno de celda".

 4
Author: James M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-16 00:33:14

Lo hice ahora mismo con una de mis cuadrículas.

  • Primero aplique el mismo margen a cada elemento dentro de la cuadrícula. Puedes hacer esto mannualy, usando estilos, o lo que quieras. Digamos que quieres un espaciado horizontal de 6px y un espaciado vertical de 2px. Luego agrega márgenes de "3px 1px" a cada hijo de la cuadrícula.
  • Luego elimine los márgenes creados alrededor de la cuadrícula (si desea alinear los bordes de los controles dentro de la cuadrícula a la misma posición de la cuadrícula). Haz esto establecer un margen de "-3px-1px" en la cuadrícula. De esa manera, otros controles fuera de la cuadrícula se alinearán con los controles más externos dentro de la cuadrícula.
 3
Author: isierra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-25 11:58:43

Me encontré con este problema mientras desarrollaba algún software recientemente y se me ocurrió preguntar POR QUÉ? ¿Por qué han hecho esto...la respuesta estaba justo delante de mí. Una fila de datos es un objeto, por lo que si mantenemos la orientación del objeto, entonces el diseño para una fila en particular debe separarse (supongamos que necesita reutilizar la visualización de la fila más adelante en el futuro). Así que empecé a usar paneles de pila de databound y controles personalizados para la mayoría de las pantallas de datos. Las listas han hecho la aparición ocasional pero sobre todo la cuadrícula se ha utilizado solo para la organización de la página principal (Encabezado, Área de Menú, Área de Contenido, Otras Áreas). Sus objetos personalizados pueden administrar fácilmente cualquier requisito de espaciado para cada fila dentro del panel de pila o cuadrícula (una sola celda de cuadrícula puede contener todo el objeto de fila. Esto también tiene el beneficio adicional de reaccionar correctamente a los cambios de orientación,expandir/colapsar, etc.

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

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

O

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

Sus controles personalizados también heredarán el DataContext si usa datos binding...my beneficio personal favorito de este enfoque.

 3
Author: Matt Meikle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-14 16:21:00

Como se indicó antes, cree una clase GridWithMargins. Aquí está mi ejemplo de código de trabajo

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>
 2
Author: Paul Baxter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-21 20:30:47

Una posibilidad sería agregar filas y columnas de ancho fijo para actuar como el relleno / margen que está buscando.

También puede considerar que está limitado por el tamaño de su contenedor, y que una cuadrícula se volverá tan grande como el elemento contenedor o su ancho y altura especificados. Simplemente podría usar columnas y filas sin ancho o alto establecido. De esa manera, por defecto, dividen uniformemente el espacio total dentro de la cuadrícula. Entonces sería sólo una cuestión de centrado tus elementos vertical y horizontalmente dentro de tu cuadrícula.

Otro método podría ser envolver todos los elementos de la cuadrícula en una cuadrícula fija con una sola fila y columna que tenga un tamaño y margen fijos. Que su cuadrícula contiene cajas de ancho / alto fijas que contienen sus elementos reales.

 1
Author: Adam Lenda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-23 17:36:14

En uwp (Windows10FallCreatorsUpdate versión y superior)

<Grid RowSpacing="3" ColumnSpacing="3">
 1
Author: Kursat Turkay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-05 20:10:30

Me sorprende no haber visto esta solución publicada todavía.

Viniendo de la web, frameworks como bootstrap usarán un margen negativo para retirar filas / columnas.

Puede ser un poco detallado (aunque no tan malo), funciona y los elementos están espaciados y dimensionados uniformemente.

En el siguiente ejemplo utilizo una raíz StackPanel para demostrar cómo los 3 botones están espaciados uniformemente usando márgenes. Puede usar otros elementos, simplemente cambie la x interior: Escriba desde el botón a su elemento.

La idea es simple, use una cuadrícula en el exterior para sacar los márgenes de los elementos de sus límites a la mitad de la cantidad de la cuadrícula interna (usando márgenes negativos), use la cuadrícula interna para espaciar uniformemente los elementos con la cantidad que desea.

introduzca la descripción de la imagen aquí

    <StackPanel>
        <Grid>
            <Grid.Resources>
                <Style TargetType="{x:Type Grid}">
                    <Setter Property="Margin" Value="-5 0"/>
                </Style>
            </Grid.Resources>

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

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Button Grid.Column="0" Content="Btn 1" />
                <Button Grid.Column="1" Content="Btn 2" />
                <Button Grid.Column="2" Content="Btn 3" />
            </Grid>

        </Grid>

        <TextBlock FontWeight="Bold" Margin="0 10">
            Test
        </TextBlock>
    </StackPanel>
 1
Author: AntonB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-16 18:20:17

Aunque no puede agregar margen o relleno a una Cuadrícula, podría usar algo como un Marco (o contenedor similar), al que puede aplicarlo.

De esa manera (si muestra u oculta el control en un botón, haga clic en decir), no necesitará agregar margen en cada control que pueda interactuar con él.

Piense en ello como aislar los grupos de controles en unidades, luego aplicar estilo a esas unidades.

 0
Author: ed13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-04 18:42:08

A veces el método simple es el mejor. Solo rellena tus cuerdas con espacios. Si son solo unos pocos cuadros de texto, etc, este es, con mucho, el método más simple.

También puede simplemente insertar columnas/filas en blanco con un tamaño fijo. Extremadamente simple y se puede cambiar fácilmente.

 -3
Author: rolls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-05 01:56:19