dhiraj sakariya
dhiraj sakariya

Reputation: 41

How to pass selectedItem of Treeview item in CommandParameter of contextmenu

I have below xaml to to tree view control wiht contextmenu "Edit". When I select Edit context menu, my EditCommand method is executed in MVVM.

Problem:

I am getting parameter as "TreeView". I would like to get parameter as selected Item(where used did RMB)

 <TreeView x:Name="treeView" ItemsSource="{Binding TreeViewItems}">
   <TreeView.ContextMenu>
     <ContextMenu>
         <MenuItem Header="Edit" Command="{Binding EditCommand}" 
              CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ContextMenu}}}"/>
     </ContextMenu>
  </TreeView.ContextMenu>
</TreeView>

Can anybody guide me to what to change in CommandParameter to get Selected Item.

I have already tried below linked, but solution provided didn't work for me. [WPF treeview contextmenu command parameter [CommandParameters in ContextMenu in WPF

Upvotes: 4

Views: 2456

Answers (1)

user1286901
user1286901

Reputation: 319

Just add SelectedItem to PlacementTarget like so:

<TreeView x:Name="treeView" ItemsSource="{Binding TreeViewItems}">
   <TreeView.ContextMenu>
      <ContextMenu>
          <MenuItem Header="Edit" Command="{Binding EditCommand}" 
              CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ContextMenu}}}"/>
      </ContextMenu>
   </TreeView.ContextMenu>
</TreeView>

Update 1

ICommand implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WpfApplication1
{
  public class Command<T> : ICommand
  {
    private Action<T> _execute;
    private Predicate<T> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public Command(Action<T> execute, Predicate<T> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        if (_canExecute == null) return true;
        return _canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }
  }
}

Code behind:

using System.Collections.Generic;
using System.Windows;
using System.Linq;
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using WpfApplication1;

namespace WPF_Sandbox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<string> Data { get; set; }  = new ObservableCollection<string>();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Data.Add("A");
            Data.Add("B");
            Data.Add("C");
        }

        public ICommand EditCommand
        {
            get
            {
                return new Command<object>(Edit);
            }
        }

        private void Edit(object param)
        {
            //Your code here
        }
    }    
}

This works for me.

Upvotes: 2

Related Questions