I have a ListBox that has a style defined for ListBoxItems. Inside this style, I have some labels and a button. One that button, I want to define a click event that can be handled on my page (or any page that uses that style). How do I create an event handler on my WPF page to handle the event from my ListBoxItems style?

Here is my style (affected code only):

<Style x:Key="UsersTimeOffList"  TargetType="{x:Type ListBoxItem}">
<Button x:Name="btnRemove" Content="Remove" Margin="0,10,40,0" Click="btnRemove_Click" />



You could create a user control (.ascx) to house the listbox. Then add a public event for the page.

Public Event btnRemove()

Then on the button click event in the usercontrol

RaiseEvent btnRemove()

You can also pass objects through the event just like any other method. This will allow your user control to tell your page what to delete.

+7  A: 

Take a look at RoutedCommands.

Define your command in myclass somewhere as follows:

    public static readonly RoutedCommand Login = new RoutedCommand();

Now define your button with this command:

    <Button Command="{x:Static myclass.Login}"  />

You can use CommandParameter for extra information..

Now last but not least, start listening to your command:

In the constructor of the class you wish to do some nice stuff, you place:

    CommandBindings.Add(new CommandBinding(myclass.Login, ExecuteLogin));

or in XAML:

        <CommandBinding Command="{x:Static myclass.Login}" Executed="ExecuteLogin" />

And you implement the delegate the CommandBinding needs:

    private void ExecuteLogin(object sender, ExecutedRoutedEventArgs e)
          //Your code goes here... e has your parameter!

You can start listening to this command everywhere in your visual tree!

Hope this helps

PS You can also define the CommandBinding with a CanExecute delegate which will even disable your command if the CanExecute says so :)

PPS Here is another example: RoutedCommands in WPF

Thanks much Arcturus, that is exactly what I was looking to do and it was simple!
+5  A: 

As Arcturus posted, RoutedCommands are a great way to achieve this. However, if there's only the one button in your DataTemplate then this might be a bit simpler:

You can actually handle any button's Click event from the host ListBox, like this:

<ListBox Button.Click="removeButtonClick" ... />

Any buttons contained within the ListBox will fire that event when they're clicked on. From within the event handler you can use e.OriginalSource to get a reference back to the button that was clicked on.

Obviously this is too simplistic if your ListBoxItems have more than one button, but in many cases it works just fine.

Matt Hamilton

same problem here as two other people had - how do you tell which item the button is on?