2
votes

I am struggling with binding to parent DataContext from DataTemplate/ContextMenu control. I've already tried solutions mentioned here and here but with no luck. I'm not able to bind to neither to property or command - no exceptions are thrown, but commands are not invoked and properties are set to null.

Here's my code sample (simplified as its possible):

<Metro:MetroWindow ...>
<Window.DataContext>
    <local:MyViewModel />
</Window.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="10*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <StackPanel ... />
    <Grid Grid.Column="1">
        <Border ... />
        <ListBox x:Name="FileList" ItemsSource="{Binding AddedFiles}" Margin="5,5,5,5" SelectionMode="Multiple" SelectionChanged="ItemsSelectionChanged">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel MaxWidth="700" IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type local:FileListItem}">
                    <Grid Margin="5" Width="110" ToolTip="{Binding Path=TooltipInfo}" MouseDown="FileItemClick" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=Self}}">
                        <Grid.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="{Binding PlacementTarget.Tag.test,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" />
                                <MenuItem Header="Test command" Command="{Binding PlacementTarget.Tag.CloseCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
                            </ContextMenu>
                        </Grid.ContextMenu>
                        <Grid.RowDefinitions ... />
                        <StackPanel ...(Databinding works here!) />
                        <TextBlock ... (Databinding works here!) />
                        <Rectangle ... (Databinding works here!) />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ListBox>
    </Grid>
</Grid>

I've tried to bind Tag property with Window's DataContext via RelativeSource too (and other possible solutions found across other topics), but nothing happens. Something must be clearly wrong in my approach.

2
CloseCommand this command is in FileListItem? - WPFUser
@WPFUser Nope, Its inside ViewModel (parent DataContext). Thats the idea - to invoke command from parent DataContext using ContextMenu from single FileListItem - baka1408
then you should be accessing ListBox's DataContext. Not its Item datacontext. - WPFUser

2 Answers

5
votes

You cannot find PlacementTarget property in Grid. Change your binding like this,

 <MenuItem Header="{Binding PlacementTarget.Tag.test,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" />

or like,

<MenuItem Header="{Binding Parent.PlacementTarget.Tag.test,RelativeSource={RelativeSource Self}}" />

Also To access ViewModel's command, Access DataContext of ListBox not ListBoxItem,

 <Grid Margin="5" Width="110" ToolTip="{Binding Path=TooltipInfo}" MouseDown="FileItemClick" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode= FindAncestor, AncestorType=ListBox}}">
0
votes

Have you tried this? (note DataContext added)

<MenuItem Header="{Binding DataContext.PlacementTarget.Tag.test,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Grid}}" />