5

In my WPF application, there is a list to select an item from. The selected item will then be displayed in a ContentControl for further interaction. Depending on the type of the selected item (there can be several), an appropriate DataTemplate is used in the ContentControl. So far, this should be nothing unusual for data processing business applications.

In each DataTemplate, there are multiple TextBoxes and other controls that bind their value to a specific property of the ViewModel class. When selecting another item from the list, all of these are updated as expected. The buttons also execute their command on the correct instance of the ViewModel.

There is one context menu item that also executes a command, but this will only work for the first selected item. When another element of the same type is selected from the list, re-using the already loaded template view, the command from the context menu will always be executed on the first-selected item. So the binding is not updated to the correct instance of the ViewModel.

The only way to make the menu item use the correct ViewModel instance is to select an item of a different type so that the template is changed to another view. Only then the context menu is updated correctly.

Why won't the menu item command be updated just like any other binding in the view? It is fetched once upon loading but never updated for the view's lifetime.

1 Answer 1

7

It's not the Command binding that doesn't update, it's the DataContext that's out of date. And this is a widely known issue, once you know the right search terms...

Here's an explanation with further links:

http://www.codeproject.com/Articles/162784/WPF-ContextMenu-Strikes-Again-DataContext-Not-Upda

Here's the relevant part of that article:

The workaround is to explicitly bind menu's data context to parent's datacontext as follows:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext,
    RelativeSource={RelativeSource Self}}">

This magical spell tells WPF to create a permanent binding between the menu's data context and its "placement target" (i.e. parent) data context, which continues to work even after parent's data context is changed. You need this spell only if you expect parent's data context to change during the life of the parent.

Another solution I've previously found was to manually set the context menu's DataContext to the window's DataContext in the Opened event. This requires additional C# code in the code-behind file and may need to be adapted to different scenarios. So I think the XAML-only way above is better.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.