Salü zäme
Ich möchte eine ContextMenue auf den Combobox-Item einbauen, um daraus ein Command zu starten, mit welchem ein Eintrag gelöscht werden kann ("Aus der Liste entfernen").
Ich habe diese so eingebaut:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Aus Liste entfernen"
Command="{Binding ItemEntfernenCommand}">
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
Aber irgendwie scheint es nicht zu funktionieren. Der Command-Befehl wird nicht aktiviert. Die Command-Eigenschaft funktioniert, diese habe ich an einem Button getestet.
Was habe ich mir hier falsch überlegt?
Moin,
ich nehme an, dass der Command nicht im DataContext des Items, sondern eine Ebene darüber vorhanden ist.
Für das Binding kannst du dann einen BindingProxy zur Hilfe nehmen.
Das liegt daran, dass das ContextMenu nicht im Visual Tree liegt.
Der Binding Proxy ist eine Möglichkeit (vermutlich die bessere), es gibt auch die Möglichkeit über das Tag Attribut:
https://stackoverflow.com/questions/15033522/wpf-contextmenu-woes-how-do-i-set-the-datacontext-of-the-contextmenu
BindingProxy
👍
Das ContextMenu
würde ich aber nicht über das ItemTemplate
definieren, sondern über den ItemContainerStyle
.
Zudem würde ich dem Command auch das aktuelle Element als Parameter übergeben, dann ist es auch eindeutig, welches Element entfert werden soll.
Sieht dann so aus
<ComboBox ItemsSource="{Binding Items}">
<ComboBox.Resources>
<c:BindingProxy x:Key="DataContext" Data="{Binding}"/>
</ComboBox.Resources>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem
Header="Item entfernen"
Command="{Binding Source={StaticResource DataContext}, Path=Data.ItemEntfernenCommand}"
CommandParameter="{Binding}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
und im ViewModel
public class MainViewModel : Utils.ObservableObject
{
public MainViewModel()
{
Items = new ObservableCollection<string>(new List<string> { "123", "456", "789" });
ItemEntfernenCommand = new Utils.RelayCommand(ItemEntfernenCommandExecute);
}
private void ItemEntfernenCommandExecute(object obj)
{
var value = (string)obj;
Items.Remove(value);
}
ObservableCollection<string> _items;
ICommand _itemEntfernenCommand;
public ObservableCollection<string> Items
{
get { return _items; }
set { Set(ref _items, value); }
}
public ICommand ItemEntfernenCommand
{
get { return _itemEntfernenCommand; }
set { Set(ref _itemEntfernenCommand, value); }
}
}