How to get the binded Item from a listbox when a button is clicked

I have a ListBox control which contains a number of items (these are UserControls), the ItemsSource is bound to an ObservableCollection. All that part works well, the ListBox shows each item in the collection as desired.

However, I would like to place a "remove" button next to each user control so that when the user clicks the button, that item is removed from the list. After some research, and a few attempts at solving this issue myself, I have currently got the following code:


<ListBox ItemsSource="{Binding Path=MyItems}">
            <StackPanel Orientation="Horizontal">
                <c:MyControl Text="{Binding Path=ItemText}" />
                <c:CustomButton Text="Remove" Click="RemoveButton_Click"/>


public ObservableCollection<MyItem> MyItems { get; set; }

private void RemoveButton_Click(object sender, RoutedEventArgs e)
    var button = sender as CustomButton;
    var item = button.DataContext as MyItem;

The problem I am having is that item is null, and the reason for this is because button.DataContext is of type CustomButton, where as I was expecting it to be of type MyItem.

What am I missing so that the buttons DataContext will be the correct MyItem object? Or is there something else I can use to get the bound item from within the click event? What reason would cause the DataContext to reference itself?


As per the OP's request:

Your CustomButton is setting it's DataContext to itself, either in XAML:

<Button x:Class="My.CustomButton"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
   <!-- ... -->

or in code:

public CustomButton()
   DataContext = this;

which is wrong. Remove that.

Need Your Help

Recommendations for an in memory database vs thread safe data structures

java database concurrency

TLDR: What are the pros/cons of using an in-memory database vs locks and concurrent data structures?

Elevating a ProcessBuilder process via UAC?

java processbuilder elevation

I'm trying to run an external executable, but apparently it needs elevation. The code is this, modified from an example of using ProcessBuilder (hence the array with one argument) :