I am trying to dynamically create a Context Menu for a data grid that passes in the selected menu item (Mvvm). I want the DataContext to be the same for the for the context menu as the grid.
I have the following Xaml
<Grid>
<!-- Cut some other stuff -->
<Border Grid.Row="2" BorderBrush="Black" BorderThickness="1">
<DataGrid x:Name="MyDataGrid" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=GridData}" AutoGenerateColumns="False" IsReadOnly="True" GridLinesVisibility="None" SelectionUnit="Cell" SelectionMode="Single">
<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding ContextMenuActions}">
<MenuItem Header="{Binding DisplayName}" Command="{Binding Command}" />
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="DataOne" Width="130" Binding="{Binding Path=DataOne}"/>
<DataGridTextColumn Header="DataTwo" Width="100" Binding="{Binding Path=DataTwo}"/>
<DataGrid.Columns>
<DataGrid.InputBindings>
<MouseBinding Gesture="RightClick" Command="{Binding DataGridRightClick}" CommandParameter="{Binding ElementName=MyDataGrid, Path=SelectedCells}" />
</DataGrid.InputBindings>
</DataGrid>
</Border>
</Grid>
and the following classes for my data context that I use for my datagrid and would also like to use for my context menu (I have cut out all the data grid population code for readability ) and menuitems
public class DataViewModel : ViewModelBase // Implements INotifyPropertyChanged
{
// All code that populates the grid has been removed
public ObservableCollection<MenuItemViewModel> ContextMenuActions { get; set; }
public ICommand DataGridRightClick { get; private set; }
public MarketDataViewModel()
{
DataGridRightClick = new RelayCommand(RightClick);
}
public void RightClick(object obj)
{
MenuItemViewModel menuItem = new MenuItemViewModel("Test", new RelayCommand(TestCall));
ContextMenuActions.Add(menuItem); // I ensure this is added on the gui thread
MenuItemViewModel menuItem1 = new MenuItemViewModel("Test2", new RelayCommand(TestCall));
ContextMenuActions.Add(menuItem1); // I ensure this is added on the gui thread but for
}
private void TestCall(object obj)
{
// want to pass in the selected menuitem
}
}
public class MenuItemViewModel
{
public MenuItemViewModel(string displayName,ICommand command)
{
DisplayName = displayName;
Command = command;
}
public string DisplayName { get; set; }
public ICommand Command { get; set; }
}
Currently when I click on the datagrid the right click event gets called and runs fine but an empty context menu appears on the grid.
Thanks, Nick
You need to bind to the DataContext.ContextMenuActions
of the parent DataGrid
. The easiest way to achieve this is by using the following binding:
<ContextMenu ItemsSource="{Binding DataContext.ContextMenuActions, ElementName=MyDataGrid}" ...