left - wpf button padding not working
WPF: cuadrĂcula con columna/margen de fila/relleno? (12)
A veces, el método simple es el mejor. Simplemente rellene sus cadenas con espacios. Si solo son unos pocos cuadros de texto, etc., este es, de lejos, el método más simple.
También puede simplemente insertar columnas / filas en blanco con un tamaño fijo. Extremadamente simple y puedes cambiarlo fácilmente.
¿Es posible especificar un margen y / o margen para filas o columnas en una cuadrícula de WPF?
Por supuesto, podría agregar columnas adicionales para espaciar las cosas, pero esto parece ser un trabajo para el relleno / márgenes (dará mucho más XAML). ¿Alguien ha derivado de la Grilla estándar para agregar esta funcionalidad?
Aunque no puede agregar margen o relleno a una Grilla, puede usar algo como un Marco (o contenedor similar), que puede aplicar.
De esa forma (si muestra u oculta el control de un botón, haga clic en decir), no necesitará agregar un margen en cada control que pueda interactuar con él.
Piense en ello como aislar los grupos de controles en unidades, y luego aplicar estilo a esas unidades.
Como se dijo antes, crea 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>
Lo hice ahora mismo con una de mis redes.
- Primero aplique el mismo margen a cada elemento dentro de la cuadrícula. Puedes hacer esta manualidad, usar estilos o lo que quieras. Digamos que quiere un espaciado horizontal de 6px y un espaciado vertical de 2px. Luego agrega márgenes de "3px 1px" a cada elemento secundario de la cuadrícula.
- A continuación, elimine los márgenes creados alrededor de la cuadrícula (si desea alinear los bordes de los controles dentro de la cuadrícula con la misma posición de la cuadrícula). Haga esto estableciendo un margen de "-3px -1px" en la cuadrícula. De esta forma, otros controles fuera de la red se alinearán con los controles externos dentro de la red.
Me encontré con este problema mientras desarrollaba un software recientemente y se me ocurrió preguntar ¿POR QUÉ? Por qué han hecho esto ... la respuesta estaba justo frente a mí. Una fila de datos es un objeto, por lo que si mantenemos la orientación del objeto, entonces el diseño de una fila en particular debe separarse (supongamos que necesita volver a usar la visualización de filas más tarde en el futuro). Así que comencé a utilizar paneles de pila de datos y controles personalizados para la mayoría de las pantallas de datos. Las listas han aparecido ocasionalmente, pero la mayoría de 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 los requisitos de espaciado para cada fila dentro del panel o cuadrícula de la pila (una sola celda puede contener todo el objeto de la fila. Esto también tiene el beneficio adicional de reaccionar adecuadamente a los cambios de orientación, expansión / colapso, 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>
Tus controles personalizados también heredarán el DataContext si utilizas el enlace de datos ... mi beneficio favorito personal de este enfoque.
Pensé que agregaría mi propia solución porque nadie ha mencionado esto todavía. En lugar de diseñar un UserControl basado en Grid, puede dirigir los controles contenidos en la grilla 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 TextBlocks, puede hacer esto:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="10"/>
</Style>
Que es como el equivalente a "relleno de celda".
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 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>
Una posibilidad sería agregar filas y columnas de ancho fijo para actuar como el relleno / margen que está buscando.
También podría considerar que está limitado por el tamaño de su contenedor, y que una red será tan grande como el elemento contenedor o su ancho y alto especificados. Simplemente podría usar columnas y filas sin ningún ancho o alto establecido. De esa forma, predeterminan dividir de manera uniforme el espacio total dentro de la cuadrícula. Entonces sería simplemente una cuestión de centrar tus elementos vertical y horizontalmente en tu cuadrícula.
Otro método podría ser ajustar todos los elementos de la cuadrícula en una cuadrícula fija con una única fila y columna que tenga un tamaño y un margen fijos. Que su cuadrícula contiene cuadros de ancho / altura fijos que contienen sus elementos reales.
Use un control de 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:
en uwp (versión Windows10FallCreatorsUpdate y superior)
<Grid RowSpacing="3" ColumnSpacing="3">
RowDefinition
y ColumnDefinition
son de tipo ContentElement
y Margin
es estrictamente una propiedad FrameworkElement
. Entonces, para su pregunta, "¿es posible fácilmente?", La respuesta es un no definitivo. Y no, no he visto paneles de diseño que demuestren este tipo de funcionalidad.
Puede agregar filas o columnas adicionales como sugirió. Pero también puede establecer márgenes en un elemento de Grid
sí, o cualquier cosa que entraría dentro de una Grid
, por lo que esa es su mejor solución por el momento.
Puede escribir su propia clase GridWithMargin
, heredada de Grid
, y anular el método ArrangeOverride
para aplicar los márgenes