WPF ContextMenu woes: How do I set the DataContext of the ContextMenu? WPF ContextMenu woes: How do I set the DataContext of the ContextMenu? wpf wpf

WPF ContextMenu woes: How do I set the DataContext of the ContextMenu?


The ContextMenu is outside of the visual tree. Below is the xaml that should get you the datacontext:

<ItemsControl ItemsSource="{Binding Markers}" Tag="{Binding ElementName=outerControl, Path=DataContext}">   ...   <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">      <MenuItem Header="Edit"                Command="{Binding EditCommand}" />   </ContextMenu>   ...</ItemsControl>

This post explains how this works.


You can use a markupextension:

using System;using System.Windows.Controls;using System.Windows.Markup;using System.Xaml;[MarkupExtensionReturnType(typeof(ContentControl))]public class RootObject : MarkupExtension{    public override object ProvideValue(IServiceProvider serviceProvider)    {        var rootObjectProvider = (IRootObjectProvider)serviceProvider.GetService(typeof(IRootObjectProvider));        return rootObjectProvider?.RootObject;    }}

It lets you do:

<ItemsControl ItemsSource="{Binding Markers}">   ...   <ContextMenu DataContext="{Binding DataContext, Source={local:RootObject}}">      <MenuItem Header="Edit"                Command="{Binding EditCommand}" />   </ContextMenu>   ...</ItemsControl>


I don't like use Tag. I prefer attached property.

You need add attached property:

public static readonly DependencyProperty DataContextExProperty =   DependencyProperty.RegisterAttached("DataContextEx",                                       typeof(Object),                                        typeof(DependencyObjectAttached));public static Object GetDataContextEx(DependencyObject element){    return element.GetValue(DataContextExProperty);}public static void SetDataContextEx(DependencyObject element, Object value){    element.SetValue(DataContextExProperty, value);}

In XAML:

<Button attached:DependencyObjectAttached.DataContextEx="{Binding ElementName=MyDataContextElement, Path=DataContext}">    <Button.ContextMenu>        <ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.(attached:DependencyObjectAttached.DataContextEx)}">        </ContextMenu>    </Button.ContextMenu></Button>