musefan
musefan

Reputation: 48435

How can I keep dynamic sized controls aligned?

I have a WPF application and I am looking for a way to align some Label and TextBox controls so that the TextBox controls are always inline, but also allow for the Label content to be dynamic (which should move the TextBoxes as required).

It is a little hard to explain so here are a couple of screenshots that should show my requirements...

Before:

enter image description here

After:

enter image description here

Notice how the first TextBox shifts to the right in order to make room for the longer text, while the second TextBox also shifts to keep inline with the first. (The behavior I want is similar to that of an HTML table with two rows of two cells each)

Keeping in mind I am fairly new to WPF (so I may be going down the wrong road completely), I have used a couple of StackPanels in order to cater for the dynamic sized labels. However, the problem of course is that both StackPanels do not know about each other.

Here is my current code:

<StackPanel Orientation="Horizontal">
    <Label Content="Label 1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
    <Label Content="Label 2" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="200"/>
</StackPanel>

Is there anyway to get what I want by using StackPanels? If not, what other controls or methods can I use to meet my requirements?

Upvotes: 3

Views: 378

Answers (2)

Sheridan
Sheridan

Reputation: 69987

Just use a Grid:

<Grid Grid.Row="2" VerticalAlignment="Top">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        ...
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Grid.Column="0" Text="Name" Style="{StaticResource 
    LabelStyle}" />
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Name, 
    UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxStyle}" />
    <TextBox Grid.Row="1" Grid.Column="0" Text="Age" Style="{StaticResource 
    LabelStyle}" />
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Age, 
    UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxStyle}" />
    ...
</Grid>

Upvotes: 1

Chris
Chris

Reputation: 5514

If you want the columns to be sized the same for all controls, simply use a Grid.

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

    <Label Grid.Row="0" Grid.Column="0" Content="Longer Label 1"/>
    <TextBox Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
    <Label Grid.Row="1" Grid.Column="0" Content="Label 2" />
    <TextBox Grid.Row="1" Grid.Column="1" TextWrapping="Wrap"/>    
</Grid>

With this setup, the first column will size to fit the widest label, and the second will take up the rest.

Upvotes: 3

Related Questions