仅限ListViewItem的ContextMenu

时间:2013-09-20 16:07:04

标签: c# wpf contextmenu listviewitem

我有一个上下文菜单 - 问题是我需要它才能在单击listviewitem时打开。现在,如果我点击列表视图中的任何位置或标题中,它将打开。

<ListView> 
    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem Header="More Info" Command="{Binding MoreInfo}" />
        </ContextMenu>
     </ListView.ContextMenu>
     <ListView.View> 
         <GridView> 
           <!-- columns and stuff here -->
         </GridView>
     </ListView.View>
 </ListView>

我已经尝试将ContextMenu添加为资源并将其作为样式应用,但这会破坏命令(单击“更多信息”应该打开一个对话框窗口,不会这样工作)

<ListView.Resources>
    <ContextMenu x:Key="ItemContextMenu">
        <MenuItem Header="More Info" Command="{Binding MoreInfo}" Background="WhiteSmoke" />
    </ContextMenu>
</ListView.Resources>
<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}" >
        <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
    </Style>
</ListView.ItemContainerStyle>

所以不确定如何将上下文菜单限制为listviewitem并使命令有效。

2 个答案:

答案 0 :(得分:17)

在模板中使用命令绑定中的RelativeSource,它将起作用:

<ListView.Resources>
    <ContextMenu x:Key="ItemContextMenu">
        <MenuItem Header="More Info" Command="{Binding Path=DataContext.MoreInfo, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" />
    </ContextMenu>
</ListView.Resources>

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}" >
        <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
    </Style>
</ListView.ItemContainerStyle>

答案 1 :(得分:0)

扩展这篇非常有用的帖子...如果您的 ContextMenuControlTemplate 中有自定义按钮或其他对象,我将上面的答案与 Closing ContextMenu with Templated MenuItems 的答案结合起来,以便当用户点击 Button 时,ContextMenu 通常仅使用 XAML 关闭。这花了大约 10 个小时来组装。希望它可以节省您的时间。支持 MVVM ICommand 用法。我还使用了 [this post][2] 中的 Style 作为 ContextMenu 以消除 90 年代的外观。

<ListView.Resources>
    <ContextMenu x:Key="ItemContextMenu" Style="{StaticResource HorizontalContextMenu}">
        <MenuItem>
            <MenuItem.Template>
                <ControlTemplate>
                    <Grid MinHeight="50" MinWidth="50">
                        <Button Style="{StaticResource CloseAppButton}" Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" >
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="Button.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ContextMenu.IsOpen)" Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <sys:Boolean>False</sys:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>
                        </Button>
                    </Grid>
                </ControlTemplate>
            </MenuItem.Template>
        </MenuItem>

        <MenuItem>
            <MenuItem.Template>
                <ControlTemplate>
                    <Grid MinHeight="50" MinWidth="50">
                        <Button Style="{StaticResource AddButton}" Command="{Binding Path=DataContext.TestCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" >
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="Button.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ContextMenu.IsOpen)" Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <sys:Boolean>False</sys:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>
                        </Button>
                    </Grid>
                </ControlTemplate>
            </MenuItem.Template>
        </MenuItem>

        <MenuItem>
            <MenuItem.Template>
                <ControlTemplate>
                    <Grid MinHeight="50" MinWidth="50">
                        <Button Style="{StaticResource PluginInfoButton}" Command="{Binding Path=DataContext.TestCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" >
                            <Button.Triggers>
                                <EventTrigger RoutedEvent="Button.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ContextMenu.IsOpen)" Storyboard.Target="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <sys:Boolean>False</sys:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Button.Triggers>
                        </Button>
                    </Grid>
                </ControlTemplate>
            </MenuItem.Template>
        </MenuItem>
    </ContextMenu>

</ListView.Resources>
<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}" >
        <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    </Style>
</ListView.ItemContainerStyle>