views:

311

answers:

1

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. **

A: 

You have two options.
Note: the code samples I added here a similar, but not same as your samples.

Move the definition of the ContextMenu inside the DataGrid defintion as follows:

<WpfToolkit:DataGrid
   x:Name="DataGrid_Standard"
   IsSynchronizedWithCurrentItem="True"
   Background="Transparent" 
   ItemsSource="{Binding FullGridData}" 
   ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}">
   <WpfToolkit:DataGrid.ContextMenu>
       <ContextMenu>
           <MenuItem Command="{Binding CutCommand}" Header="Test" />
           <MenuItem Header="Copy"/>
           <MenuItem Header="Paste"/>
       </ContextMenu>
   </WpfToolkit:DataGrid.ContextMenu>
</WpfToolkit:DataGrid>

Or better add a CommandReference to your Resources and set the Command in the MenuItem to a StaticResource as follows:

<Window.Resources>
    <c:CommandReference x:Key="MyCutCommandReference" Command="{Binding CutCommand}" />

    <ContextMenu x:Key="columnHeaderMenu">
        <MenuItem Command="{StaticResource MyCutCommandReference}" Header="Test" />
        <MenuItem Header="Copy"/>
        <MenuItem Header="Paste"/>
    </ContextMenu>

    <Style TargetType="{x:Type Primitives:DataGridColumnHeader}" x:Key="DefaultColumnHeaderStyle">
        <Setter Property="ContextMenu" Value="{DynamicResource columnHeaderMenu}" />
    </Style>

</Window.Resources>

<WpfToolkit:DataGrid
   x:Name="DataGrid_Standard"
   IsSynchronizedWithCurrentItem="True"
   Background="Transparent" 
   ItemsSource="{Binding FullGridData}" 
   ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"/>
Zamboni
@Zamboni -- I am using your second solution since I want context menu only for header.Actually now the commands are getting associated but my menu-item is disabled. I am using DelegateCommand class for binding. Its really strange Why is my menu-item disabled??
Guru Charan
It worked for me, but I am not sure what implementation of DelegateCommand you are using; look at the second paramater that controls whether the command is enabled or not. I added a sample here:cutCommand = new DelegateCommand<object>(CutColumn, CanCutCommand);private bool CanCutCommand(object obj){ return true;}
Zamboni
I am using the DelegateCommand available in mvvm toolkit from codeplex. I have seen some websites in which they say its bug. The links are as follows : http://connect.microsoft.com/VisualStudio/feedback/details/421816/wpf-command-based-context-menu-item-initially-disabled http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7bd75a7c-eab4-4f3a-967b-94a9534a7455
Guru Charan