title: WPF DataGrid ContextMenu Command binding to MVVMLight RelayCommand<T> not always working
body: <p>I have a WPF <code>DataGrid</code> for which I want to add a <code>ContextMenu</code> using MVVM. This <code>DataGrid</code> resides in a <code>UserControl</code> (I removed a bunch of stuff which I don't think have to do with the essence of the problem):</p>
  
  <pre><code>&lt;UserControl x:Class="Legend.MarkerMultiStatisticsControl"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:legend="clr-namespace:Legend"
               Name="Self"
               mc:Ignorable="d" 
               d:DesignHeight="300" d:DesignWidth="300"&gt;
      &lt;GroupBox Header="{Binding ElementName=Self, Path=StaisticsData.Title}"&gt;
          &lt;DockPanel&gt;
              &lt;DataGrid 
                        DataContext="{Binding ElementName=Self}"
                        ItemsSource="{Binding ElementName=Self, Path=StaisticsData.Statistics}"
                        SelectionMode="Single"
                        CurrentCell="{Binding ElementName=Self, Path=CurrentCell, Mode=OneWayToSource}"&gt;
                  &lt;DataGrid.ContextMenu&gt;
                      &lt;ContextMenu DataContext="{Binding RelativeSource={RelativeSource Mode=Self}, Path=PlacementTarget.DataContext}"
                                   ItemsSource="{Binding Path=Commands}"&gt;
                          &lt;ContextMenu.ItemContainerStyle&gt;
                              &lt;Style TargetType="MenuItem"&gt;
                                  &lt;Setter Property="Header" Value="{Binding Header}"&gt;&lt;/Setter&gt;
                                  &lt;Setter Property="Command" Value="{Binding Command, diag:PresentationTraceSources.TraceLevel=High}"&gt;&lt;/Setter&gt;
                                  &lt;Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}, Path=DataContext.CurrentLegendCell}"&gt;&lt;/Setter&gt;
                              &lt;/Style&gt;
                          &lt;/ContextMenu.ItemContainerStyle&gt;
                      &lt;/ContextMenu&gt;
                  &lt;/DataGrid.ContextMenu&gt;
              &lt;/DataGrid&gt;
          &lt;/DockPanel&gt;
      &lt;/GroupBox&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>This control has a <code>DependencyProperty</code> called <code>Command</code> to which I bind the menu's <code>ItemsSource</code> and its type is <code>ObservableCollection&lt;LegendCommand&gt;</code> with <code>LegendCommand</code> being</p>
  
  <pre><code>public class LegendCommand : ObservableObject
  {
      private string _header;
      private ICommand _command;
  
      public string Header
      {
          get { return _header; }
          set { Set(()=&gt;Header, ref _header, value); }
      }
  
      public ICommand Command
      {
          get { return _command; }
          set { Set(() =&gt; Command, ref _command, value); }
      }
  }
  </code></pre>
  
  <p>These commands are generated in different places in my view models.</p>
  
  <p>In one place (inside an <code>Adapter</code> class whose <code>Commands</code> are bound to the control's <code>Commands</code>) I have the following:</p>
  
  <pre><code>Commands.Add(new LegendCommand
              {
                  Header = "From inside adapter...",
                  Command = new RelayCommand&lt;LegendCellInfo&gt;(info =&gt;
                  {
                      MessageBox.Show(string.Format("State: {0}, Property: {1}", info.State, info.PropertyName));
                  })
              });
  </code></pre>
  
  <p>And in a different place (the view model which holds the <code>Adapter</code>) I have the following:</p>
  
  <pre><code>adapter.Commands.Add(new LegendCommand
              {
                  Header = "Select",
                  Command = new RelayCommand&lt;LegendCellInfo&gt;(info =&gt;
                  {
                      // selection logic
                  })
              });
  </code></pre>
  
  <p>My problem is that the "From inside adapter..." command is executed but "Select" isn't. I put a breakpoint in the "Select" code but it's never called.</p>
  
  <p>The binding of the <code>ContextMenu</code>'s <code>ItemsSource</code> to the <code>Commands</code> property works as I see both options in the menu.
  The binding of the <code>ICommans</code>'s probably works because one of the commands is executed.</p>
  
  <p>I debugged the code and binding and have the following info:</p>
  
  <p>The <code>Commands</code> collection holds two elements whose hash codes are 40262542 and 26818564 (got them from running <code>adapter.Commands[0].Command.GetHashCode()</code> and <code>adapter.Commands[1].Command.GetHashCode()</code> in Visual Studio's Immediate Window).</p>
  
  <p>The binding tracing gives the following output when I right-click the <code>DataGrid</code>:</p>
  
  <pre><code>System.Windows.Data Warning: 56 : Created BindingExpression (hash=11440639) for Binding (hash=54536677)
  System.Windows.Data Warning: 58 :   Path: 'Command'
  System.Windows.Data Warning: 60 : BindingExpression (hash=11440639): Default mode resolved to OneWay
  System.Windows.Data Warning: 61 : BindingExpression (hash=11440639): Default update trigger resolved to PropertyChanged
  System.Windows.Data Warning: 62 : BindingExpression (hash=11440639): Attach to System.Windows.Controls.MenuItem.Command (hash=54276594)
  System.Windows.Data Warning: 67 : BindingExpression (hash=11440639): Resolving source 
  System.Windows.Data Warning: 70 : BindingExpression (hash=11440639): Found data context element: MenuItem (hash=54276594) (OK)
  System.Windows.Data Warning: 78 : BindingExpression (hash=11440639): Activate with root item LegendCommand (hash=5940773)
  System.Windows.Data Warning: 108 : BindingExpression (hash=11440639):   At level 0 - for LegendCommand.Command found accessor RuntimePropertyInfo(Command)
  System.Windows.Data Warning: 104 : BindingExpression (hash=11440639): Replace item at level 0 with LegendCommand (hash=5940773), using accessor RuntimePropertyInfo(Command)
  System.Windows.Data Warning: 101 : BindingExpression (hash=11440639): GetValue at level 0 from LegendCommand (hash=5940773) using RuntimePropertyInfo(Command): RelayCommand`1 (hash=40262542)
  System.Windows.Data Warning: 80 : BindingExpression (hash=11440639): TransferValue - got raw value RelayCommand`1 (hash=40262542)
  System.Windows.Data Warning: 89 : BindingExpression (hash=11440639): TransferValue - using final value RelayCommand`1 (hash=40262542)
  System.Windows.Data Warning: 56 : Created BindingExpression (hash=31617173) for Binding (hash=54536677)
  System.Windows.Data Warning: 58 :   Path: 'Command'
  System.Windows.Data Warning: 60 : BindingExpression (hash=31617173): Default mode resolved to OneWay
  System.Windows.Data Warning: 61 : BindingExpression (hash=31617173): Default update trigger resolved to PropertyChanged
  System.Windows.Data Warning: 62 : BindingExpression (hash=31617173): Attach to System.Windows.Controls.MenuItem.Command (hash=16119107)
  System.Windows.Data Warning: 67 : BindingExpression (hash=31617173): Resolving source 
  System.Windows.Data Warning: 70 : BindingExpression (hash=31617173): Found data context element: MenuItem (hash=16119107) (OK)
  System.Windows.Data Warning: 78 : BindingExpression (hash=31617173): Activate with root item LegendCommand (hash=16131920)
  System.Windows.Data Warning: 107 : BindingExpression (hash=31617173):   At level 0 using cached accessor for LegendCommand.Command: RuntimePropertyInfo(Command)
  System.Windows.Data Warning: 104 : BindingExpression (hash=31617173): Replace item at level 0 with LegendCommand (hash=16131920), using accessor RuntimePropertyInfo(Command)
  System.Windows.Data Warning: 101 : BindingExpression (hash=31617173): GetValue at level 0 from LegendCommand (hash=16131920) using RuntimePropertyInfo(Command): RelayCommand`1 (hash=26818564)
  System.Windows.Data Warning: 80 : BindingExpression (hash=31617173): TransferValue - got raw value RelayCommand`1 (hash=26818564)
  System.Windows.Data Warning: 89 : BindingExpression (hash=31617173): TransferValue - using final value RelayCommand`1 (hash=26818564)
  </code></pre>
  
  <p>If I understand correctly, we can see that two binding operations take place - the first results in binding to <code>'RelayCommand'1 (hash=40262542)</code> and the second to <code>'RelayCommand'1 (hash=26818564)</code> - incidentally these are the hash codes for my two commands.</p>
  
  <p>Also, no exceptions or other errors occur.</p>
  
  <p>I'm stuck in my investigation. Where else to look?</p>
  
  <p><strong>UPDATE 1</strong>:
  When I change the code in "Select" command to the following instead of the code I had before:</p>
  
  <pre><code>adapter.Commands.Add(new LegendCommand
              {
                  Header = "Select",
                  Command = new RelayCommand&lt;LegendCellInfo&gt;(info =&gt;
                  {
                      MessageBox.Show("yes");
                  })
              });
  </code></pre>
  
  <p>then the code starts working all of a sudden...</p>
  
  <p><strong>UPDATE 2</strong>:
  The original command uses members of the <code>Adapter</code> class. Searching online for problems with MVVMLight <code>RelayCommand</code> and member functions found this SO question: <a href="https://stackoverflow.com/questions/19468086/relaycommand-with-argument-throwing-methodaccessexception">RelayCommand with Argument throwing MethodAccessException</a>
  (but obviously I want to continue using MVVMLight...)</p>
  
  <p><strong>UPDATE 3</strong>: Read the MVVMLight code for <code>RelayCommand</code> and it doesn't save a hard reference to the method so I think that nothing is keeping the lambda alive. Will refactor the code now and update here if it works.</p>