3

I have an Obseravable Collection of Items. The collection is displayed in the treeview. I want to enable removing an Item from the collection using context menu. I don't know how can I do that.

For instance, Let's say I have 4 treeviewitems (which means i have 4 Items in the Obseravable Collection) Now, the user wants to remove the second Item, he right clicks on the second treeviewitem, a context menu is opened and he presses on "Remove.." How can I identify which item to remove from the Collection? (I'm doing it using the Command)

The context menu looks like this:

     <ContextMenu x:Key="RemoveItemMenu">
        <MenuItem Header="Remove..." Command="RemoveItem"/>
     </ContextMenu> 

And the Command function that will be excecuted:

        private void RemoveItemExcecute()
    {
        //Removing the clicked Item out of the collection
    }
idish
  • 3,190
  • 12
  • 53
  • 85

2 Answers2

1

You can add a CommandParameter to the MenuItem. This way you'll be able to pass the item you wish to remove to the command.

<ContextMenu x:Key="RemoveItemMenu">
    <MenuItem Header="Remove..." Command="RemoveItem" CommandParameter="{Binding}" />
</ContextMenu>

You'll possibly want to modify the binding to pass the information you need. Then that information will be available to you when you handle the command:

private void RemoveItemExcecute(object param)
{
    // "param" is the command parameter passed to the command.
    MyItem item = (MyItem)param;
    MyItemCollection.Remove(item);
}
Adi Lester
  • 24,731
  • 12
  • 95
  • 110
  • I don't understand, how can I pass the item itself? – idish Dec 22 '12 at 19:04
  • @idish See my modified answer – Adi Lester Dec 25 '12 at 08:39
  • Hmm, this won't work because my TreeViewItem viewmodel representation is different than the datacontext viewmodel. I need to retrieve the data context of the treeviewitem itself, is there any way of doing it? – idish Dec 28 '12 at 20:56
0

I would refer to this answer which explains how to use Behaviors to add a SelectedItem field to your TreeView.

From there you could just refer to the SelectedTreeItem in your ViewModel's RemoveItemExecute method.

XAML:

<TreeView ItemsSource="{Binding MyCollection}">
    <e:Interaction.Behaviors>
        <behaviours:BindableSelectedItemBehavior SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" />
    </e:Interaction.Behaviors>
</TreeView>

C#:

public ObservableCollection<MyObject> MyCollection { get; set; }

public MyObject MySelectedItem { get; set; } // You'll want to use INotifyPropertyChanged magic here

private void RemoveItemExcecute()
{
    MyCollection.Remove(MySelectedItem);
}

Another option would be to use a CommandParameter to pass MySelectedItem into the function.

XAML:

<ContextMenu x:Key="RemoveItemMenu">
    <MenuItem Header="Remove..." Command="RemoveItem" CommandParameter="{Binding MySelectedItem}"/>
 </ContextMenu> 

C#:

private void RemoveItemExcecute(object param)
{
    var selectedItem = (MyObject)param;
    MyCollection.Remove(selectedItem);
}
Community
  • 1
  • 1
lumberjack4
  • 2,772
  • 4
  • 30
  • 50
  • I am sorry, but it is based on Context Menu and not on the selected item. (I'm able to do context menu not on the selected item, so it doesn't help me) – idish Dec 22 '12 at 18:59