Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

wpf - pass contextmenu parent as CommandParameter

i have a HierarchicalDataTemplate for a TreeViewItem, in the template i have a contextmenu and i want to pass as CommandParameter the ContextMenu parent - i.e the TreeViewItem owner that was right clicked at the moment, is there a way to do that? here is my template:

    <HierarchicalDataTemplate 
    x:Key="ServerTemplate"
    DataType="{x:Type models:Server}" 
    ItemsSource="{Binding Channels}"
    ItemTemplate="{StaticResource ChannelTemplate}">
    <StackPanel
        Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
        Orientation="Horizontal">
        <StackPanel.ContextMenu>
            <ContextMenu
                FontSize="14"
                FontFamily="Arial">
                <MenuItem 
                    Header="{x:Static p:Resources.ServerOperations_CommunicationSettings}"
                    Command="{Binding PlacementTarget.Tag.ServerCommunicationSettingCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContextMenu}}}"
                    CommandParameter="{Binding Path=Parent, RelativeSource={RelativeSource Mode=Self}}">
                </MenuItem>

            </ContextMenu>
        </StackPanel.ContextMenu>
        <Image 
            Source="{Binding ImageURL, Converter={StaticResource StringToImageConverter}}"
            Margin="0,0,2,0"
            Height="25"
            Width="25"/>
        <TextBlock 
            Text="{Binding ServerName}"
            Foreground="White"/>
    </StackPanel>
</HierarchicalDataTemplate>

thanks for the help

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can get the TreeViewItem by getting PlacementTarget of ContextMenu which will be StackPanel and its TemplatedParent will be ContentPresenter and its TemplatedParent will be TreeViewItem. So this will work:

CommandParameter="{Binding Path=PlacementTarget.TemplatedParent.TemplatedParent, 
                           RelativeSource={RelativeSource Mode=FindAncestor,
                                            AncestorType={x:Type ContextMenu}}}"

PlacementTarget (StackPanel) --> TemplatedParent (ContentPresenter) --> TemplatedParent (TreeViewItem)


Ideally it's not a good idea to pass UI components to ViewModel. You should pass data i.e. DataContext of TreeViewItem as you can always play with that.

In case you want to pass Server instance i.e. DataContext of TreeviewItem, you can simply do "{Binding}" since MenuItem will inherit it from StackPanel.

CommandParameter="{Binding}"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...