Ich hatte die gleiche Frage und obwohl ich nicht die Antwort fand, die ich wollte, fand ich einen Workaround, der meinen Bedürfnissen gut entsprach. Ich dachte, du würdest es gerne sehen, auch lange danach.
Anscheinend, wenn die ItemsSource
der Klasse ContextMenu
MenuItem
-Objekte enthält, landet das Symbol dort, wo es hingehört. Ich habe, wie du, ein ViewModel verwendet und wollte keine UI-Logik in meine ViewModel-Klasse einfügen.
Stattdessen habe ich einen Wertkonverter implementiert, um mein ViewModel in MenuItem
-Objekte zu transformieren. Es sah ungefähr so aus:
XAML:
...
C#-Code-Behind
private void OnBindingContextMenu(object sender, ValueConvertingEventArgs e)
{
var dataitems = e.Value as IEnumerable;
if (dataitems != null)
{
var items = dataitems.Select(data => new MenuItem()
{
Header = data.Title,
Icon = data.Icon,
Tag = data
}).ToList();
var handler = new RoutedEventHandler(this.OnContextMenuClick);
items.ForEach(item => item.Click += handler);
e.Result = items;
}
}
private void OnContextMenuClick(object sender, RoutedEventArgs e)
{
}
Discussion
Der DelegatedValueConverter
ist etwas, das ich detailliert hier beschreibe, aber es ist nicht wirklich wichtig. Du könntest deinen eigenen Wertkonverter erstellen und stattdessen verwenden.
Die Eigenschaft Title
meines ViewModels ist ein String und Icon
ist eine Instanz von Image
. Ich benutze die Tag
-Eigenschaft des Menüobjekts, um eine Referenz auf mein ViewModel zu behalten, damit ich mich während eines Klickereignisses auf die nicht-visuellen Daten darin beziehen kann.
Diese Lösung ist bequem, weil sie immer noch eine Trennung zwischen der UI und dem ViewModel bietet, obwohl ich in diesem Fall eine rein deklarative Lösung bevorzugen würde.
Ich hoffe, das hilft!