Databinding a command to Context Menu with an Observable Collection


I have a Context menu with some options. One of the options is an Observable collection and I am having issues binding my commands in my view model to them. I have seen many different ways to fix this issue, but none have worked because they do not specifically relate to my problem. Here is my code first:


<ListView ItemsSource="{Binding ListViewItems}" SelectionMode="Single"> <ListView.ContextMenu> <ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"> <MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" /> <Separator></Separator> <MenuItem Header="Status" ItemsSource="{Binding DataContext.ObservableCollectionList}" DisplayMemberPath="Name" Command="{Binding Path=DataContext.UpdateCommand}" CommandParameter="{Binding Path=SelectedItem}"/> </ContextMenu> </ListView.ContextMenu> //listviewstuff here </ListView>


public class VM : ViewModelBase { public RelayCommand UpdateCommand { get; private set; } public Action UpdateCommandAction { get; set; } public ObservableCollection<Status> ObservableCollectionList { get; set; } public VM() { this.UpdateCommand = new RelayCommand(new Action(() => this.UpdateCommandAction.DynamicInvoke()))); } }

Code-behind for the XAML view:

public partial class View { public View() { InitializeComponent(); var ViewDataContext = this.DataContext as VM; ViewDataContext .UpdateCommandAction = UpdateStatus; } private void UpdateStatus() { MessageBox.Show("test"); } }

I inserted a break point and it's not even making it to the method call. The debug output is not showing an error for me when I run the program either. What I don't understand is when I add this Command to the regular menu item that is NOT populated by a data bound list, it works fine. I would appreciate a fresh pair of eyes and some insight in to how this works.


You need to bind the command to all the child items, now you bind it on the parent which will ignore it because it has child items (opens sub-menu instead).

To bind it on the children you need the ItemContainerStyle, create a Setter for the Command there. You will need to walk up again, probably this: {Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}} (not sure about the AncestorLevel, if it does select itself instead of the parent increase it; double DataContext because you bound to DataContext.ObservableCollectionList, assuming that binding to actually work).

Likewise there is no SelectedItem in a menu, you need another Setter for CommandParameter, it will simply bind to the current item, i.e. {Binding}.

<hr />

<strong>Edit:</strong> Code example:

<MenuItem Header="Status" ItemsSource="{Binding DataContext.ObservableCollectionList}" DisplayMemberPath="Name"> <MenuItem.ItemContainerStyle> <Style TargetType="MenuItem"> <Setter Property="Command" Value="{Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}"/> <Setter Property="CommandParameter" Value="{Binding}"/> </Style> </MenuItem.ItemContainerStyle> </MenuItem>


You'll need a List<MenuItem> MenuItems to bind with ContextMenu ItemSource property as

public class MenuItem { public string Header { get; set; } public ICommand Command { get; set; } }

<strong>XAML:</strong> and set itemContainerstyle

<ContextMenu ItemsSource="{Binding MenuItems}" > <ContextMenu.ItemContainerStyle> <Style TargetType="{x:Type MenuItem}" > <Setter Property="Header" Value="{Binding Header}"/> <Setter Property="Command" Value="{Binding Command}" /> </Style> </ContextMenu.ItemContainerStyle> </ContextMenu>

And add as many contextmenu item you want in your ViewModel AS YOU WANT.


  • How to use RelativeSource Binding to create DataGrid binding to Model and ViewModel?
  • How to add ComboBox column in XCeed DataGridControl (WPF)
  • Design Time null reference error
  • Xceed datagrid showing combobox
  • No drop with basic gongsolution sample
  • Bind Combobox with huge data in WPF
  • writing to sdcard
  • Getting the new line character without System.getProperty(“line.separator”)?
  • Java - How to convert this string to date?
  • Add vertical separator and labels to R barplot
  • use grep and awk to transfer data from .srt to .csv/xls
  • Gruntfile.js - Throwing error 'Recursive process.nextTick detected\"
  • CUDA Debugging - VS on windows workstation, GPUs on Linux server?
  • WPF Listbox commands
  • Getting zero results in search using elastic4s
  • RPMs for IDAS IoTAgents GE, from Fiware
  • How do I get the list of bad records that didn't load in Bigquery?
  • SQL Query - Table Joining Problems
  • Can't remove headers after they are sent
  • How to use JavaScript to determine whether a file exists in a directory?
  • Sort List of Strings By Version
  • Problems compiling files using JOGL
  • Parsing a CSV string while ignoring commas inside the individual columns
  • Swing - Get new component under mouseReleased
  • MVC3 Razor - ListBox pre-select not working
  • How do I pass the string value parameter of the selected list item from an auto-populated dropdown l
  • Set the selected item in dropdownlist in MVC3
  • ilmerge with a PFX file
  • Spring Data JPA custom method causing PropertyReferenceException
  • Pass value from viewmodel to script in zk
  • Can I display google adwords (AdView) in javafx on android
  • Validaiting emails with Net.Mail MailAddress
  • sending/ receiving email in Java
  • Can I have the cursor start on a particular column by default in jqgrid's edit mode?
  • Cannot Parse HTML Data Using Android / JSOUP
  • Error creating VM instance in Google Compute Engine
  • JTable with a ScrollPane misbehaving
  • unknown Exception android
  • failed to connect to specific WiFi in android programmatically
  • How can I use threading to 'tick' a timer to be accessed by other threads?