DataContext not being assigned

Nov 17, 2010 at 2:00 AM

Hi - thanks for the great component. I am currently using it in a project using the MVVM pattern and Prism and came across the problem of Command property on PopupMenuItem not being bound because the DataContext for a menu item is null.

The DataContext is null because the menu is hard coded, as in the examples, in XAML. The XAML uses an ItemsControl of some kind (eg ListBox) but does not have an items source, and does not need one, since the menu items are explicitly defined. This means the Command property has not DataContext to bind to.

To fix this, I updated PopupMenu.Open to include the following code when opening:

this.ItemsControl.Items.OfType<PopupMenuItem>().ToList().ForEach(
    item => item.DataContext = item.DataContext ?? this.DataContext);
Is this expected behaviour or am I using it incorrectly?

Nov 18, 2010 at 8:19 PM

A further problem has become apparent - if I place a Prism region inside the menu (to populate it dynamically from other menus) then that region never becomes registered. The reason for this is that the RegionManagerRegistrationBehavior searches upwards through the logical tree for a RegionManager.RegionManagerProperty value - which doesn't exist since the menu is inside a popup (discussed here).

The solution is to replace the code in the original post above with a much simpler line in the PopupMenu.Open method:

this.ItemsControl.DataContext = this.ItemsControl.DataContext ?? this.DataContext;

I can then expose the RegionManger in the ViewModel my menu View uses and bind to it on my ItemsControl in the menu.

Coordinator
Nov 26, 2010 at 11:58 AM

Sorry but I haven't had the opportunity to play with Prism up to now and so I can't really test such issues.

Thanks a lot for your feedback and i'm glad you found a solution.

I've added the following lines of code to the Open event to fix it:

if (this.ItemsControl.DataContext == null)
this.ItemsControl.DataContext = this.DataContext;

You can download the latest change set here: