wpf contextmenu datacontext

WPF ContextMenu woes: ¿Cómo configuro el DataContext del ContextMenu?



(3)

El ContextMenu está fuera del árbol visual. A continuación se muestra el xaml que debe obtener el contexto de datos:

<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>

Esta post explica cómo funciona esto.

Tengo problemas para encontrar la manera de configurar el DataContext correcto en un ContextMenu .

Tengo una colección de modelos de vista que son la fuente de un ItemsControl . Cada modelo de vista tiene una colección de elementos que también son la fuente de otro ItemsControl . Cada elemento se usa para dibujar una imagen que tiene un ContextMenu . Los elementos de MenuItems en ese ContextMenu necesitan vincularse a un comando en el modelo de vista, pero el PlacementTarget del ContextMenu apunta al elemento individual.

Mi Xaml se ve así:

<ItemsControl ItemsSource="{Binding Markers"}> <ItemsControl.ItemTemplate> <DataTemplate> <ItemsControl ItemsSource="{Binding Items}"> <ItemsControl.ItemTemplate> <DataTemplate> <Image> <Image.ContextMenu> <ContextMenu> <MenuItem Header="Edit" Command="{Binding EditCommand}" /> </ContextMenu> </Image.ContextMenu> </Image> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>

¿Cómo puedo configurar el DataContext del ContextMenu en el modelo de vista padre correspondiente del elemento?


No me gusta usar Tag. Prefiero la propiedad adjunta.

Necesita agregar propiedad adjunta:

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); }

En 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>


Puedes usar 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; } }

Te deja hacer:

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