1

I struggle to bind to an ICommand in a place described in the title.

Firstly, my DataContext in this place is a Item and not my ViewModel, so I need to get around this somehow. I already did this on my ItemClickCommand, but the same solution will not work, because:

Secondly, a ContextMenu is not part of the window, and not part of the visual or logical tree. What woodoo I need to implement to get around this, I do not know.

ViewModel:

public ICommand CopyTextCommand { get; private set; }
public Constructor()
{
    CopyTextCommand = new RelayCommand(InsertToClopboard);
    Initialize();
}
private void InsertToClopboard(object parameter)
{
    // Want to get in here.
}

View:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <ListView Grid.Row="0" x:Name="MainListView" ItemsSource="{Binding Items}" Background="Transparent" BorderBrush="Transparent" Margin="0" HorizontalContentAlignment="Stretch">

            <ListView.ItemTemplate>

                <DataTemplate>
                    <Grid Margin="0" Visibility="{Binding GuiVisibility, Converter={StaticResource BoolToVisibility}}">
                        <Grid.InputBindings>
                            <MouseBinding Gesture="LeftClick"
                                      Command="{Binding Path=DataContext.ItemClickCommand, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"
                                      CommandParameter="{Binding}"/>
                        </Grid.InputBindings>

                        <Label ...
                           Content="{Binding PNR}" >
                            <Label.ContextMenu>
                                <ContextMenu>
                                    <MenuItem
                                        Name="MenuItemPnr"
                                        Header="Copy"
                                        Command="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext}" <--This does not work-->
                                        CommandParameter="test"  />
                                </ContextMenu>
                            </Label.ContextMenu>
                        </Label>

                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>

EDIT: I have tried to add a Tag with the correct binding multiple places in en xaml, but the PlacementTarget of the MenuItem is the ContextMenu. And the ContextMenu does not know the correct DataContext. How do I get around this?

Niksen
  • 79
  • 1
  • 11
  • 1
    Possible duplicate of [WPF: Binding a ContextMenu to an MVVM Command](https://stackoverflow.com/questions/3583507/wpf-binding-a-contextmenu-to-an-mvvm-command) – Sinatr Nov 06 '17 at 10:49
  • The first problem you can solve by binding to `self` as command parameter, if you need parent `DataContext`, then go through visual tree. – Sinatr Nov 06 '17 at 10:51

1 Answers1

1

Bind the Tag property of the Label to the view model and then bind the Command property of the MenuItem to the PlacementTarget of the parent ContextMenu:

<Label Content="{Binding PNR}" Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListView}}">
    <Label.ContextMenu>
        <ContextMenu>
            <MenuItem
                Name="MenuItemPnr"
                Header="Copy"
                Command="{Binding Path=PlacementTarget.Tag.CopyTextCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                CommandParameter="test"  />
        </ContextMenu>
    </Label.ContextMenu>
</Label>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • My command can't find Tag. Looks like PlacementTarget refers to the ContextMenu, and not the Label. – Niksen Nov 06 '17 at 12:17
  • The PlacementTarget of the *ContextMenu* refers to the Label. Did you really set the AncestorType to ContextMenu? – mm8 Nov 06 '17 at 12:48
  • Your answer fixes my problem! What still confused me was that Visual Studio told me that is was wrong. But running the code works. Thanks a lot! – Niksen Nov 06 '17 at 13:54