WPF - How do I get an object that is bound to a ListBoxItem back

JonBlumfeld picture JonBlumfeld · May 7, 2010 · Viewed 18.3k times · Source

here is what I would like to do. I get a List of objects from a database and bind this list to a ListBox Control. The ListBoxItems consist of a textbox and a button. Here is what I came up with. Up to this point it works as intended. The object has a number of Properties like ID, Name. If I click on the button in the ListBoxItem the Item should be erased from the ListBox and also from the database...

<ListBox x:Name="taglistBox">    
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="{x:Type ListBoxItem}">
                                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="ListBoxItem">
                                            <ContentPresenter HorizontalAlignment="Stretch"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="Tag" Value="{Binding TagSelf}"></Setter>
                            </Style>
                        </ListBox.ItemContainerStyle>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Grid HorizontalAlignment="Stretch">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <Button Grid.Column="0" Name="btTag"  VerticalAlignment="Center"  Click="btTag_Click" HorizontalAlignment="Left">
                                        <Image Width="16" Height="16" Source="/WpfApplication1;component/Resources/104.png"/>
                                    </Button>
                                    <TextBlock Name="tbtagBoxTagItem" Margin="5" Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center" />                                        
                                 </Grid>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

The Textblock.Text is bound to object.Name and the ListBoxItem.Tag to object.TagSelf (which is just a copy of the object itself).

Now my questions

  1. If I click the button in the listboxItem how do I get the listboxitem and the object bound to it back. In order to delete the object from the database I have to retrieve it somehow. I tried something like

    ListBoxItem lbi1 =
    (ListBoxItem)(taglistBox.ItemContainerGenerator.ContainerFromItem(taglistBox.Items.CurrentItem)); ObjectInQuestion t = (ObjectInQuestion) lbi1.Tag;

  2. Is there a way to automatically update the contents of the ListBox if the Itemssource changes? Right now I'm achieving that by

    taglistBox.ItemsSource = null;
    taglistBox.ItemsSource = ObjectInQuestion;

I'd appreciate any help you can give :D Thanks in advance

Answer

Kjetil Watnedal picture Kjetil Watnedal · May 7, 2010

Each ListBoxItem will have the corresponding item in the data bound collection as DataContext. And each control in the ListBoxItem.ItemTemplate will inherint the DataContext. To get the object behind the clicked button you can do the following in the click event handler:

MyClass item = (MyClass)(sender as Button).DataContext;

To have changes in the data source automatically updated to the list box, you can use an ObservableCollection.