Can someone tell me how to align and resize controls correctly when using the ItemsControl
.
I want to have a description on the left and a TextBox
on the right for multiple fields which are defined in an ObservableCollection
to end up with something like:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
but instead I'm getting this:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
I want all the textbox to be aligned based on the largest <TextBlock>
. If this was done directly in a <Grid>
control, it would be straight forward as all controls are directly in the grid and you would just have the following columns definition defined
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
I thought I could use the SharedSizeGroup
property in the <Grid>
but it still doesn't resize correctly. Instead it only displays the <TextBlock>
stretch across the <Grid>
.
Here's my code:
<Grid Grid.IsSharedSizeScope="True" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Labels" />
<ColumnDefinition Width="*" SharedSizeGroup="InputControls" />
</Grid.ColumnDefinitions>
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedTemplate.Fields}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}" Grid.Column="0" Margin="5"
VerticalAlignment="Center" Background="Red" />
<TextBox Text="{Binding Path=Value}" Grid.Column="1" Margin="5"
VerticalAlignment="Center" Background="Blue" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Any idea how I can resolve this?
Thanks.
UPDATE1: I cannot get this to work as I need it to. This is what I've got so far:
<Grid Grid.Row="1" Background="Purple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="Overall" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
This ends up displaying my layout this way:
As you can see, my TextBox
are correctly aligned based on the largest TextBlock
but my ItemsControls is not stretched all the way across. I guess that makes sense as it is within the same grid where the ColumnDefinitions
are defined.
Now, if I move the ColumnDefinitions' out this grid to the outer grid and remove all instances of
Grid.IsSharedSizeScope`, I guess the following:
Which once again is closer to what I need as my ItemsControl is now stretching all the way as I've set its Grid.ColumnSpan="2"
and my TextBox
are still aligned to the TextBlock
and are stretching all the way across but the problem now is that the TextBlock
should be smaller as the Column is set to Auto
but they appear to behave as if the column was set to *
and I guess I'm losing the purpose of using IsSharedSizeScope
since it has been removed.
Now if I add IsSharedSizeScope="True"
to the outer grid, I get the following result:
Again, this is close to what I want as my ItemsControl is stretched, my textboxes are also stretch but they are no longer aligned to the largest TextBlock
.
Finally, if I add Grid.IsSharedSizeScope="True"
to ItemsControl
as originally suggested by @mm8,
<Grid Grid.Row="1" Background="Purple" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.ColumnSpan="2" >
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<!--<TextBlock Text="Invoice Number" Grid.Column="0" Margin="5" VerticalAlignment="Center"/>
<TextBox Text="InvoiceNumber" Grid.Column="1" Margin="5" VerticalAlignment="Center"/>-->
</Grid>
I get the following:
Which brings me back to square one, though the definitions are different?
I need to achieve the following:
What am I doing wrong??
Thanks.
Try to set the Grid.IsSharedSizeScope
property of the ItemsControl
itself:
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
Grid.IsSharedSizeScope="True">
Synchronizing the width of elements in an ItemsControl: https://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/