Tony Vitabile
Tony Vitabile

Reputation: 8594

How to create binding for ListBox with TextBox in ListItemTemplate

I have a simple View Model class (I'm omitting the INPC implementation for brevity):

public class MyViewModel : INotifyPropertyChanged
{
    public int ID { get; set; }

    public ObservableCollection<int> Items { get; }

    public int SelectedItemIndex { get; set; }
}

My problem is with my XAML. The above class is contained in another ObservableCollection in the parent object, so it's coded as a DataTemplate:

<DataTemplate x:Key="MyDataTemplate" DataType="x:MyViewModel">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0"
               Target="{Binding ElementName=ID}">
            <Bold>ID:</Bold>
        </Label>
        <TextBox Grid.Column="1"
                 x:Name="ID"
                 Height="25"
                 Text="{Binding Path=ID}"
                 VerticalAlignment="Top" />

        <Label Grid.Column="2"
               Target="Items:">
            <Bold>Rooms:</Bold>
        </Label>

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

            <ListBox Grid.Column="0"
                     Grid.Row="0"
                     Grid.RowSpan="2"
                     ItemsSource="{Binding Path=Items}"
                     SelectedIndex="{Binding Path=SelectedItemIndex, Mode=TwoWay}"
                      x:Name="Items">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="{x:Type system:Int32}">
                        <TextBox Text="{Binding Path=., Mode=TwoWay}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

            <Button Grid.Column="1"
                    Grid.Row="0"
                    Content="{Binding Path=AddButtonCaption}"
                    Command="local:EditorCommands.AddElement"
                    CommandParameter="{Binding}"
                    Height="25"
                    VerticalAlignment="Top" />

            <Button Grid.Column="1"
                    Grid.Row="1"
                    Content="{Binding Path=DeleteButtonCaption}"
                    Command="local:EditorCommands.DeleteElement"
                    CommandParameter="{Binding}"
                    Height="25"
                    VerticalAlignment="Top" />
        </Grid>
    </Grid>
</DataTemplate>

There are a few problems with this XAML:

  1. The TextBox does not occupy the full width of the ListBox.
  2. The binding on the same TextBox isn't working.

How do I fix these problems?

Upvotes: 0

Views: 49

Answers (1)

Mark Feldman
Mark Feldman

Reputation: 16119

1) Give your ListBox ItemContainerStyle property a style and set its HorizontalContentAlignment property:

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</ListBox.ItemContainerStyle>

2) Are you sure? Seems to be working fine for me. If you want it to update as you type then set the binding's UpdateSourceTrigger property to PropertyChanged:

<TextBox Grid.Column="1"
        x:Name="_ID"
        Height="25"
        Text="{Binding Path=ID, UpdateSourceTrigger=PropertyChanged}"
        VerticalAlignment="Top" />

Note that I've changed the TextBox's x:Name to "_ID" here because it was causing a conflict with the way I'm testing it (ID is also a property in the Window. Could also be confusing whatever framework is handling your bindings, so if the above doesn't work then try that as well.

Upvotes: 1

Related Questions