Fat Cat
Fat Cat

Reputation: 131

How to identify the clicked button belongs to which listbox item?

In WPF programming, I have a problem to write the button click event handler. Because the button is inside a listbox item(a part of datatemplate), and when the button is clicked, I can't tell which item it belongs to. Is there any solution? SOS - -

Upvotes: 1

Views: 3056

Answers (3)

Tony Hopkinson
Tony Hopkinson

Reputation: 20330

ListBox.selectedItem and listbox.SelectedIndex will be set as part of clicking the button.

Assuming the items in the list box are say type MyListBoxItem

void SomeButtonClick(Object sender, EventArgs e)
{
  ListBox lb = sender as ListBox
  if (lb != null)
  {
    MyListBoxItem item = lb.SelectedItem As MyListBoxItem;
    if (item != Null)
    {
      item.MethodRelatedToButton(); // maybe
    }
  }
}

Amplified as requested

Upvotes: 0

Moha Dehghan
Moha Dehghan

Reputation: 18472

It seems that you have bound a list box to a collection, and your buttons are part of your Data Template or Item Template.
You can bind the Tag property of the buttons to your data object:

<DataTemplate DataType="{x:Type c:Person}">
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <TextBlock>Name:</TextBlock>
            <TextBlock Text="{Binding Path=Name}"/>
        </StackPanel>
        <Button Click="Button_Click" Tag="{Binding Path=.}">Click me!</Button>
    </StackPanel>
</DataTemplate>

And the click event:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button b = (Button)sender;
    Person p = (Person)b.Tag;
    MessageBox.Show(p.Name);
}

But, as other people suggest, you can use the DataContext property of the Button. It already points to the Person object in my example.

I think by using the Tag property, you have more control over what you want to access in you event handler.

There are many ways to do everything! Choose the one that best suits you.

Upvotes: 9

ionden
ionden

Reputation: 12786

You can get that information from the DataContext.

public class Person {

    public string Name { get; set; }
    public int Age { get; set; }

}

 Persons = new ObservableCollection<Person>() {

      new Person() { Name = "John", Age = 30 },
      new Person() { Name = "Tim", Age = 48 }
 };

 lbPersons.DataContext = Persons;

 private void person_Clicked(object sender, RoutedEventArgs e) {

        Button cmd = (Button)sender;
        if (cmd.DataContext is Person) {
            Person p = (Person)cmd.DataContext;
        }
    }

And in XAML:

<Window.Resources>
    <DataTemplate x:Key="UserTemplate" >
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="{Binding Path=Name}" Width="50"/>
            <TextBlock Text="{Binding Path=Age}" Width="20"/>
            <Button Content="Click" Click="person_Clicked"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox IsSynchronizedWithCurrentItem="True" Name="lbPersons" ItemsSource="{Binding}" ItemTemplate="{StaticResource UserTemplate}" />
</Grid>

Upvotes: 3

Related Questions