WPF: grelha com margem/enchimento da coluna/linha?

é fácil especificar uma margem e / ou estofamento para linhas ou colunas numa grelha WPF?

Eu poderia, naturalmente, adicionar colunas extra para espaçar as coisas, mas isto parece ser um trabalho para estofar/margens (ele dará Muito XAML simplier). Alguém derivado da grade padrão para adicionar esta funcionalidade?

Author: Dave Clemmer, 2009-08-24

13 answers

Você poderia escrever a sua própria classe GridWithMargin, herdada de Grid, e sobrepor o método ArrangeOverride para aplicar as margens

 15
Author: Thomas Levesque, 2009-08-28 15:50:18

RowDefinition e ColumnDefinition são do tipo ContentElement, e Margin é estritamente uma propriedade FrameworkElement. Portanto, para a sua pergunta, "é fácil" a resposta é um não muito definitivo. E não, não vi nenhum painel de layout que demonstrasse este tipo de funcionalidade.

Pode adicionar linhas ou colunas extra como sugeriu. Mas você também pode definir margens em um elemento Grid, ou qualquer coisa que vá dentro de um Grid, então essa é a sua melhor solução por agora.

 72
Author: Charlie, 2014-01-21 17:51:25

Utilize um controlo Border fora do controlo da célula e defina o enchimento para isso:

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


Fonte:

 24
Author: samad, 2017-05-24 23:40:25

Dava-te jeito algo assim:

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

Ou se não precisar das legendas:

<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, 2014-05-08 15:18:15
Pensei em Adicionar a minha própria solução porque ainda ninguém mencionou isto. Em vez de projetar um UserControl baseado na grade, você pode direcionar os controles contidos na grade com uma declaração de estilo. Tem o cuidado de adicionar estofamento/margem a todos os elementos sem ter que definir para cada um, o que é pesado e trabalhoso.Por exemplo, se a sua grelha contém apenas bloqueios de texto, pode fazer isto:
<Style TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="10"/>
</Style>
Que é o equivalente a"enchimento celular".
 4
Author: James M, 2016-02-16 00:33:14
Fi-lo agora mesmo com uma das minhas grelhas.
  • primeiro aplique a mesma margem a todos os elementos da grelha. Você pode fazer isso manualmente, usando estilos, ou o que quiser. Vamos dizer que você quer um espaçamento horizontal de 6px e um espaçamento vertical de 2px. Em seguida, você adiciona margens de "3px 1px" para cada criança da grade.
  • depois remova as margens criadas em torno da grelha (se quiser alinhar os contornos dos controlos dentro da grelha com a mesma posição da grelha). Fazer esta configuração uma margem de "- 3px-1px " para a grade. Dessa forma, outros controles fora da grade serão alinhados com os controles mais exteriores dentro da grade.
 3
Author: isierra, 2012-07-25 11:58:43
Deparei-me com este problema ao desenvolver algum software recentemente e ocorreu-me perguntar porquê? Porque é que eles fizeram isto?..a resposta estava mesmo à minha frente. Uma linha de dados é um objeto, então se mantivermos a orientação do objeto, então o projeto para uma determinada linha deve ser separado (suponha que você precisa reutilizar a exibição da linha mais tarde no futuro). Então eu comecei a usar painéis de pilha de banco de dados e controles personalizados para a maioria dos displays de dados. As listas aparência, mas principalmente a grade foi usada apenas para a organização primária da Página (Cabeçalho, área de Menu, Área de conteúdo, outras áreas). Seus objetos personalizados podem facilmente gerenciar quaisquer requisitos de espaçamento para cada linha dentro do Painel Da pilha ou grade (uma única célula da grade pode conter todo o objeto da linha. Isto também tem o benefício adicional de reagir corretamente às mudanças de orientação, 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>

Ou

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

Os seus controlos personalizados também herdarão o texto de dados se o seu utilizar os dados binding...my benefício pessoal favorito desta abordagem.

 3
Author: Matt Meikle, 2015-02-14 16:21:00
Como foi dito antes de criar uma classe de GridWithMargins. Aqui está o meu exemplo de código de trabalho
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, 2017-02-21 20:30:47

Uma possibilidade seria adicionar linhas e colunas de largura fixa para agir como o revestimento / margem que você está procurando.

Você também pode considerar que você está limitado pelo tamanho do seu recipiente, e que uma grade se tornará tão grande quanto o elemento contendo ou sua largura e altura especificadas. Você poderia simplesmente usar colunas e linhas sem largura ou altura definida. Dessa forma, eles default para dividir uniformemente o espaço total dentro da grade. Então seria apenas uma questão de centrando os seus elementos verticalmente e horizontalmente dentro da sua grelha.

Outro método pode ser embrulhar todos os elementos da grelha numa grelha fixa com uma única linha e coluna que tenha um tamanho e uma margem fixos. Que a sua grelha contém caixas fixas de largura / altura que contêm os seus elementos reais.

 1
Author: Adam Lenda, 2011-03-23 17:36:14

In uwp (Windows10FallCreatorsUpdate version and above)

<Grid RowSpacing="3" ColumnSpacing="3">
 1
Author: Kursat Turkay, 2017-12-05 20:10:30
Estou surpreendido por ainda não ter visto esta solução publicada.

Vindo da web, frameworks como o bootstrap irão usar uma margem negativa para retirar linhas / colunas.

Pode ser um pouco descritivo (embora não seja assim tão mau), funciona e os elementos são uniformemente espaçados e dimensionados.

No exemplo abaixo eu uso uma raiz StackPanel para demonstrar como os 3 botões são uniformemente espaçados usando margens. Você poderia usar outros elementos, basta mudar o interior x: Digite de botão para o seu elemento.

A ideia é simples, use uma grelha do lado de fora para puxar as margens dos elementos para fora dos seus limites por metade da quantidade da grelha interna (usando margens negativas), use a grelha interna para espaçar uniformemente os elementos com a quantidade que deseja.

enter image description here

    <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, 2018-08-16 18:20:17

Embora não possa adicionar margem ou enchimento a uma grelha, pode usar algo como uma moldura (ou um contentor semelhante), a que pode aplicá-la.

Assim (se mostrar ou esconder o controlo num botão, carregue em dizer), não terá de adicionar margem em cada controlo que possa interagir com ele.

Pense nisso como isolando os grupos de controlos em unidades, depois aplicando estilo a essas unidades.

 0
Author: ed13, 2015-08-04 18:42:08
Às vezes, o método simples é o melhor. Basta remexer as cordas com espaços. Se é apenas algumas caixas de texto etc Este é de longe o método mais simples.

Também pode simplesmente inserir colunas/linhas em branco com um tamanho fixo. Extremamente simples e você pode facilmente mudá-lo.

 -3
Author: rolls, 2017-02-05 01:56:19