Reputation: 1692
I'm trying to build a simple (in terms of design) screen which will allow users to enter multiple rows of data.
The format of the screen is 4 columns (TextBox
, TextBox
, ComboBox
, TextBox
), with new rows added dynamically.
I have tried 2 approaches initially - one using a DataGrid
, and one using a ListView
.
The DataGrid
caused many headaches with items retaining focus when they were clicked out of, and the ListView
prevented me from being able to consistently access the underlying cell, instead returning the bound data object represented by the row.
My current approach uses a custom component which represents a row, and contains the 3 TextBox
objects, and one ComboBox
object.
One or more of these objects are displayed in a ListBox
.
This approach allows for handling events more consistently, but is visually less straightforward to get working.
Currently, when a row is displayed, the first 3 columns in the grid
(which have an explicitly defined width
) display fine, but the textbox
in the final column does not expand to fill the available width.
The relevant code for the panel:
<DockPanel LastChildFill="True" Name="basePanel">
<Grid x:Name="baseGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="55"></ColumnDefinition>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Name="txtYear" Grid.Column="0" Style="{StaticResource txtComponentStyle}" Text="{Binding Path=RatingYear, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Name="txtArrears" Grid.Column="1" Style="{StaticResource txtComponentStyle}" Text="{Binding Path=ArrearsAmount, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox Name="cmbChangeCode" Grid.Column="2" ItemsSource="{Binding Path=ChangeCodes, Mode=OneTime}" SelectedItem="{Binding Path=ChangeCode}" />
<TextBox Name="txtComments" Grid.Column="3" Style="{StaticResource txtComponentStyle}" Text="{Binding Path=Comments, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" />
</Grid>
</DockPanel>
When I select a row in the ListBox
, I can see that the object itself fills the entire width, yet the text box in the final column only expands to fit the content.
Setting the width in the column definition to * should (as I understand it) cause the column to expand to fille the available space, and setting the HorizontalAlignment
property on the textbox
to Stretch should cause the text box to fill the column.
The code below creates the ListBox
.
<UserControl.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0.5" Margin="1">
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch" Background="DarkSlateBlue">
<Controls:ArrearsListEntry />
</DockPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<DockPanel LastChildFill="True" Background="Red">
<ListBox IsSynchronizedWithCurrentItem="True" Name="lstRowData" ItemsSource="{Binding Path=Rows}" />
</DockPanel>
Is there a way to bind the width of the text box to the actual width of the column, or a property which will cause the text box to automatically expand to the available width?
Upvotes: 0
Views: 1067
Reputation: 128061
The ListBoxItem's Content is left aligned by default. Add a Setter for the HorizontalContentAlignment
to your ListBoxItem Style:
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="ContentTemplate">
...
</Setter>
</Style>
Upvotes: 2