4

I need help with the layout of a WPF application.

I've tried different combinations of DockPanel, StackPanel, WrapPanel, Grid and UniformGrid. But I can't seem to align the text of all the controls. I understand the checkboxes won't align due to control size, but the first one should still line up.

How would you arrange these controls?

| GroupBox | GroupBox   |                 |
|  -> cbx     ->tbx+lbl | TextBox+button  |
|  -> cbx     ->tbx+lbl | ComboBox+button |
| TabControl                              |

I've been trying to size all controls to default height 23 but that seems to make things worse due to the margins I'm trying to use.

<Grid x:Name="MasterGrid" Margin="10">

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <DockPanel Grid.Row="0">
            <GroupBox Header="CheckBox" Margin="5 0 0 0">
                <StackPanel Margin="5">
                    <StackPanel.Resources>
                        <Style TargetType="{x:Type CheckBox}">
                            <Setter Property="Margin" Value="0 5 0 0"/>
                        </Style>
                    </StackPanel.Resources>
                    <CheckBox Content="XXXX"/>
                    <CheckBox Content="XXXX"/>
                </StackPanel>
            </GroupBox>

            <GroupBox Header="Label + TextBox" Margin="5 0 0 0">
                <StackPanel Grid.IsSharedSizeScope="True">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Content="XXXX:" Margin="0 5 0 0" Height="23"/>
                        <TextBox Grid.Column="1" Text="XXXX" VerticalContentAlignment="Center" Margin="0 5 5 0" Height="23"/>
                    </Grid>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Content="XXXX:" Margin="0 5 0 0"/>
                        <TextBox Grid.Column="1" Text="XXXX" VerticalContentAlignment="Center" Margin="0 5 5 0" Height="23"/>
                    </Grid>
                </StackPanel>
            </GroupBox>

            <Grid VerticalAlignment="Center" Margin="0 5 0 0">
                <Grid.Resources>
                    <Style TargetType="{x:Type Button}">
                        <Setter Property="Height" Value="23"/>
                        <Setter Property="Margin" Value="5 5 0 0"/>
                        <Setter Property="Width" Value="75"/>
                    </Style>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="Height" Value="23"/>
                        <Setter Property="Margin" Value="5 5 0 0"/>
                    </Style>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="Height" Value="23"/>
                        <Setter Property="Margin" Value="5 5 0 0"/>
                    </Style>
                </Grid.Resources>

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

                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>

                <TextBox  Grid.Row="0" Grid.Column="0" Text="XXXXXXXXXX" VerticalContentAlignment="Center"/>
                <Button   Grid.Row="0" Grid.Column="1" Content="Browse"/>
                <Button   Grid.Row="1" Grid.Column="1" Content="Load"/>
                <ComboBox Grid.Row="1" Grid.Column="0" SelectedItem="XXXXXXXXXX"/>
            </Grid>
        </DockPanel>

        <!-- Imported Data Collection -->
        <TabControl Grid.Row="1" Margin="0 5 0 5"/>
    </Grid>

I've gone through a ton of existing questions and experimented with each answer (couple examples)

(Background for future question searchers: tool is for browsing through log files. Select the folder path -> combobox is populated with file names -> select file to load into tabcontrol. The two groupboxes contain options for how to handle different file formats)

Community
  • 1
  • 1
user1002479
  • 235
  • 2
  • 4
  • 12

2 Answers2

0

Kinda hacky, since the items which appear in the group boxes aren't actually located within them, but the alignment seems spot-on. I tweaked some of the sizes and margins to more closely match the Windows UI Guidelines.

<Grid x:Name="MasterGrid" Margin="11">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
  </Grid.RowDefinitions>

  <Grid>
    <Grid.Resources>
      <Style TargetType="Label">
        <Setter Property="Padding" Value="0,0,5,0"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
      </Style>
      <Style TargetType="CheckBox">
        <Setter Property="Padding" Value="0,0,5,0"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
      </Style>
      <Style TargetType="TextBox">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="MinHeight" Value="23"/>
        <Setter Property="MinWidth" Value="75"/>
      </Style>
      <Style TargetType="ComboBox">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="MinHeight" Value="23"/>
        <Setter Property="MinWidth" Value="75"/>
      </Style>
      <Style TargetType="Button">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="MinHeight" Value="23"/>
        <Setter Property="MinWidth" Value="75"/>
      </Style>
    </Grid.Resources>

    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="7" />
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="11"/>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="7" />
      <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" MinHeight="23"/>
      <RowDefinition Height="Auto" MinHeight="23"/>
      <RowDefinition Height="7"/>
      <RowDefinition Height="Auto" MinHeight="23"/>
      <RowDefinition Height="Auto" MinHeight="11"/>
    </Grid.RowDefinitions>

    <GroupBox Grid.Column="0" Grid.RowSpan="5" Header="CheckBox"/>

    <CheckBox Grid.Column="0" Grid.Row="1" Margin="11,0" Content="XXXX"/>
    <CheckBox Grid.Column="0" Grid.Row="3" Margin="11,0" Content="XX"/>

    <GroupBox Grid.Column="2" Grid.RowSpan="5" Margin="0,0,0,0" Header="TextBox"/>

    <Grid Grid.Column="2" Grid.Row="1" Grid.RowSpan="3" Margin="11,0,11,0">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="7"/>
        <RowDefinition Height="Auto"/>
      </Grid.RowDefinitions>

      <Label Grid.Column="0" Grid.Row="0" Content="XXXX"/>
      <TextBox Grid.Column="1" Grid.Row="0"/>

      <Label Grid.Column="0" Grid.Row="2" Content="XX"/>
      <TextBox Grid.Column="1" Grid.Row="2"/>
    </Grid>

    <Label Grid.Column="4" Grid.Row="1" Content="XXXX"/>
    <TextBox Grid.Column="5" Grid.Row="1" />
    <Button Grid.Column="7" Grid.Row="1" Content="XXXX"/>

    <Label Grid.Column="4" Grid.Row="3" Content="XXXXXX"/>
    <ComboBox Grid.Column="5" Grid.Row="3" />
    <Button Grid.Column="7" Grid.Row="3" Content="XXXX"/>
  </Grid>

  <!-- Imported Data Collection -->
  <TabControl Grid.Row="1" Margin="0,11,0,0"/>
</Grid>

To better see how the upper grid is split up (the one directly within MasterGrid), set ShowGridLines="True".

Mike Strobel
  • 25,075
  • 57
  • 69
  • I didn't mention it in the original post, but I have additional groupboxes of controls that are visible/collapsed depending on what the user does. Kinda hoping for a Dock/StackPanel approach so it's extensible. Cool idea though I didn't know you could arrange controls like that (inside groupbox but not really) – user1002479 Nov 10 '14 at 22:27
0

Using the same pattern you used, so GroupBoxes with Grid Inside,remove the DockPanel, apply simply a rule for the Height property of the Rows definition, like "23", and all the controls will be aligned.

This is the code:

<Grid x:Name="MasterGrid" Margin="10">

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <GroupBox Grid.Row="0" Grid.Column="0" Header="CheckBox" Margin="5 0 0 0">                
            <StackPanel Margin="5">
                <StackPanel.Resources>
                    <Style TargetType="{x:Type CheckBox}">
                        <Setter Property="Margin" Value="0 5 0 0"/>                       
                    </Style>
                </StackPanel.Resources>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <CheckBox Grid.Row="0" Content="XXXX" Height="23" Margin="0 5 0 0"/>
                    <CheckBox Grid.Row="1" Content="XXXX" Height="23" Margin="0 5 0 0"/>
                </Grid>
            </StackPanel>
        </GroupBox>

        <GroupBox Grid.Row="0" Grid.Column="1" Header="Label + TextBox" Margin="5 0 0 0">
            <StackPanel Grid.IsSharedSizeScope="True">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Content="XXXX:" Margin="0 5 0 0" Height="23"/>
                    <TextBox Grid.Column="1" Text="XXXX" VerticalContentAlignment="Center" Margin="0 5 5 0" Height="23"/>
                </Grid>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Content="XXXX:" Margin="0 5 0 0"/>
                    <TextBox Grid.Column="1" Text="XXXX" VerticalContentAlignment="Center" Margin="0 5 5 0" Height="23"/>
                </Grid>
            </StackPanel>
        </GroupBox>

        <GroupBox  Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2"  VerticalAlignment="Center" Margin="0 5 0 0">
        <Grid>
            <Grid.Resources>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Height" Value="23"/>
                    <Setter Property="Margin" Value="5 5 0 0"/>
                    <Setter Property="Width" Value="75"/>
                </Style>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Height" Value="23"/>
                    <Setter Property="Margin" Value="5 5 0 0"/>
                </Style>
                <Style TargetType="{x:Type ComboBox}">
                    <Setter Property="Height" Value="23"/>
                    <Setter Property="Margin" Value="5 5 0 0"/>
                </Style>
            </Grid.Resources>

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

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

            <TextBox  Grid.Row="0" Grid.Column="0" Text="XXXXXXXXXX" VerticalContentAlignment="Center"  Margin="0 5 5 0"/>
            <Button   Grid.Row="0" Grid.Column="1" Content="Browse"  Margin="0 5 5 0"/>
            <Button   Grid.Row="1" Grid.Column="1" Content="Load"  Margin="0 5 5 0"/>
            <ComboBox Grid.Row="1" Grid.Column="0" SelectedItem="XXXXXXXXXX"  Margin="0 5 5 0"/>
        </Grid>
        </GroupBox>

        <!-- Imported Data Collection -->
        <TabControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" Margin="0 5 0 5"/>
    </Grid>

This is the result

Final Result

Hope it helps.

Stefano Bafaro
  • 915
  • 10
  • 20