WPF: Grid with column/row margin/padding?

前端 未结 15 1069
梦毁少年i
梦毁少年i 2020-12-07 23:57

Is it easily possible to specify a margin and/or padding for rows or columns in a WPF Grid?

I could of course add extra columns to space things out,

相关标签:
15条回答
  • 2020-12-08 00:22

    I did it right now with one of my grids.

    • First apply the same margin to every element inside the grid. You can do this mannualy, using styles, or whatever you like. Lets say you want an horizontal spacing of 6px and a vertical spacing of 2px. Then you add margins of "3px 1px" to every child of the grid.
    • Then remove the margins created around the grid (if you want to align the borders of the controls inside the grid to the same position of the grid). Do this setting a margin of "-3px -1px" to the grid. That way, other controls outside the grid will be aligned with the outtermost controls inside the grid.
    0 讨论(0)
  • 2020-12-08 00:23

    I ran into this problem while developing some software recently and it occured to me to ask WHY? Why have they done this...the answer was right there in front of me. A row of data is an object, so if we maintain object orientation, then the design for a particular row should be seperated (suppose you need to re-use the row display later on in the future). So I started using databound stack panels and custom controls for most data displays. Lists have made the occasional appearance but mostly the grid has been used only for primary page organization (Header, Menu Area, Content Area, Other Areas). Your custom objects can easily manage any spacing requirements for each row within the stack panel or grid (a single grid cell can contain the entire row object. This also has the added benefit of reacting properly to changes in orientation, expand/collapses, etc.

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

    or

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

    Your Custom controls will also inherit the DataContext if your using data binding...my personal favorite benefit of this approach.

    0 讨论(0)
  • 2020-12-08 00:29

    As was stated before create a GridWithMargins class. Here is my working code example

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

    Usage:

    <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>
    
    0 讨论(0)
  • 2020-12-08 00:29

    Sometimes the simple method is the best. Just pad your strings with spaces. If it is only a few textboxes etc this is by far the simplest method.

    You can also simply insert blank columns/rows with a fixed size. Extremely simple and you can easily change it.

    0 讨论(0)
  • 2020-12-08 00:31

    Edited:

    To give margin to any control you could wrap the control with border like this

    <!--...-->
        <Border Padding="10">
                <AnyControl>
    <!--...-->
    
    0 讨论(0)
  • 2020-12-08 00:32

    Use a Border control outside the cell control and define the padding for that:

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


    Source:

    • Original Source
    • and from Way Back Machine
    0 讨论(0)
提交回复
热议问题