Laden...

ContextMenue auf ComboBox-Item

Erstellt von BJA-CH vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.675 Views
B
BJA-CH Themenstarter:in
59 Beiträge seit 2017
vor 6 Jahren
ContextMenue auf ComboBox-Item

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?

709 Beiträge seit 2008
vor 6 Jahren

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.

P
441 Beiträge seit 2014
vor 6 Jahren

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

D
985 Beiträge seit 2014
vor 6 Jahren

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