views:

199

answers:

3

Hi there

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

A: 

Use ObservableCollection to see instant automatic changes

Get the SelectedItem using the DataContext

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var btn = sender as Button; 
    myListBox.SelectedItem = btn.DataContext; 
}

You should have a SelectedItem property in your viewmodel bound to the listbox's selectedItem. Delete that particular item from your ObservableCollection. Your listbox will reflect changes.

Veer
+3  A: 

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.

Kjetil Watnedal
+1  A: 

To Question 2: Use an ObservableCollection. This implements INotifyCollectionChanged so items will be added and removed as the collection changes.

To Question 1: Cast the sender as a button and use it's DataContext. This will be the item it's bound to. If you also need to get the ListBoxItem itself, you can you the VisualTreeHelper.GetParent() to search up the tree.

Stephan