wpfbindingcontextmenudatatemplateelementname

Bind to parent control from within context menu within data template


I'm wanting to bind to a parent control from a context menu within a datatemplate.

Unfortunately I'm restricted to .net 3.5 and can't use the x:reference extension introduced in .net 4.

Below is an example of what I'm trying to do

<Window x:Class="WpfApplication17.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication17"
    Name="window">

    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Car}">
            <Rectangle Width="100" Height="100" Fill="Red">
                <Rectangle.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="{Binding Colour}"/>
                        <MenuItem Header="{Binding ElementName=window, Path=ActualWidth}"/>
                    </ContextMenu>
                </Rectangle.ContextMenu>
            </Rectangle>
        </DataTemplate>
    </Window.Resources>
</Window>

But I get "Cannot find source for binding with reference 'ElementName=window'" error due to the context menu not being part of the visual tree.

Edit :

That works great! .. however, it doesn't seem to work when I use a composite collection such as the following

<Window.Resources>
        <DataTemplate DataType="{x:Type local:Car}">
            <Rectangle Width="100" Height="100" Fill="Red"
               Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
                <Rectangle.ContextMenu>
                    <ContextMenu>
                        <ContextMenu.ItemsSource>
                            <CompositeCollection>
                                <MenuItem Header="{Binding Colour}"/>
                                <MenuItem Header="{Binding Path=PlacementTarget.Tag.ActualWidth, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                            </CompositeCollection>
                        </ContextMenu.ItemsSource>
                    </ContextMenu>

                    <!--<ContextMenu>
                        <MenuItem Header="{Binding Colour}"/>
                        <MenuItem Header="{Binding Path=PlacementTarget.Tag.ActualWidth, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                    </ContextMenu>-->

                </Rectangle.ContextMenu>
            </Rectangle>
        </DataTemplate>
    </Window.Resources>

Solution

  • Please try this:

    <DataTemplate DataType="{x:Type local:Car}">
        <Rectangle Width="100" Height="100" Fill="Red"
                   Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
            <Rectangle.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="{Binding Colour}"/>
                    <MenuItem Header="{Binding Path=PlacementTarget.Tag.ActualWidth, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                </ContextMenu>
            </Rectangle.ContextMenu>
        </Rectangle>
    </DataTemplate>
    

    See my answer here too.