Wpf – Context Menu items command binding WPF using MVVM

commandcontextmenudata-bindingmvvmwpf

I know this question has been asked many times in different ways in many websites and also in StackOverFlow but all the answers I found are not helping me ot to be precise I am not able to understand them and implement in my application. So I thought of putting some code from my application so that you people can help me better.

Problem Statement : I am using a WPF DataGrid. I have added a Context Menu and I have 3 options Cut,Copy,Paste. I am using MVVM for development. I want to DataBind these options to Commands in my ViewModel. But I am unable to do the same. The context menu options are not getting data bound at all !!!

This is my Grid Code in XAML :

<custom:DataGrid  
      x:Name="DataGrid_Standard"   
      Grid.Row="1" Grid.Column="1"   
      AutoGenerateColumns="False"                                                           
      IsSynchronizedWithCurrentItem="True"   
      Background="Transparent"
      ItemsSource="{Binding FullGridData}" 
      ItemContainerStyle="{StaticResource defaultRowStyle}"
      ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"                         
      Grid.ColumnSpan="2">

Then I have a ContextMenu and a Style for Header Element

<ContextMenu x:Key="columnHeaderMenu">
   <MenuItem Command="{Binding CutCommand}"
             Header="Test" />
   <MenuItem Header="Copy"/>
   <MenuItem Header="Paste"/>
</ContextMenu>
<Style TargetType="{x:Type custom:DataGridColumnHeader}" x:Key="DefaultColumnHeaderStyle">
    <Setter Property="ContextMenu" Value="{DynamicResource columnHeaderMenu}" >
</Style>

This line goes in my constructor

public Window1()
{            
   this.DataContext = new AppData();
}

This code goes in my AppData class:

public class AppData  
{ 
    private IList<GridData> fullGridData = new ObservableCollection<GridData>();<br> 
    public IList<GridData> FullGridData
    {
        get { return fullGridData; }
        set { fullGridData = value; }
    }

    private DelegateCommand<object> cutCommand;
    public DelegateCommand<object> CutCommand
    {
        get
        {
            if (cutCommand == null)
            {
                cutCommand = new DelegateCommand<object>(CutColumn);
            }
            return cutCommand;
        }
    }

    private void CutColumn(object obj)
    {
        //some code goes here
    }   
}

** I want to know exactly where am I doing wrong?? Why is the DataBinding not happening??
Please help me regarding this. Please provide me the sample code or modification in my present code from which I can achieve it. **

Best Answer

I had the same issue. The command bindings stopped working once I moved them to the ViewModel from code behind. And in the viewmodel I had to change my ICommand from RoutedCommand to DelegateCommand. I was able to get it working in the following way -

Add Opened eventhandler to your context menu -

<ContextMenu x:Key="columnHeaderMenu" Opened="ContextMenu_Opened">
    <MenuItem Command="{Binding CutCommand}" Header="Test" />
    <MenuItem Header="Copy"/>
    <MenuItem Header="Paste"/>
</ContextMenu>

In the code behind, you would assign your ViewModel to the context menu's DataContext -

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
    ContextMenu menu = sender as ContextMenu;
    menu.DataContext = _vm;
}