相对于按钮放置上下文菜单

时间:2013-06-20 21:47:02

标签: c# wpf xaml mvvm

我正在尝试完成所描述的here,除了使用Rectangle而不是Button。我做了答案中描述的内容(以及许多其他内容),并且我无法将其显示为相对于矩形显示(在我的情况下,按钮使用了矩形)。

我使用矩形作为按钮,因为我不喜欢按钮的鼠标悬停效果,使用矩形而不是构建自定义按钮似乎更容易。作为一个注释,即使我在Expression Blend 4中使用按钮,我也遇到了同样的问题。

这是我的矩形的XAML:

        <Rectangle x:Name="rectangle" HorizontalAlignment="Left" MouseDown="MenuClicked" Height="55" VerticalAlignment="Top" Width="135" Grid.ColumnSpan="2" Margin="0,1,0,0" ContextMenuService.Placement="Bottom">
        <Rectangle.ContextMenu>
            <ContextMenu x:Name="Menu" >

                <MenuItem x:Name="LoadXML" Header="Load XML" Command="{Binding Command}" CommandParameter="BrowseXML"/>
                <MenuItem x:Name="SaveXML" Header="Save XML" Command="{Binding Command}" CommandParameter="SaveXML"/>
                <MenuItem x:Name="SaveBinary" Header="Save Binary" Command="{Binding Command}" CommandParameter="SaveBinary"/>
                <MenuItem x:Name="SaveText" Header="Save Text" Command="{Binding Command}" CommandParameter="SaveText"/>
            </ContextMenu>
        </Rectangle.ContextMenu>

        <Rectangle.Fill>
            <ImageBrush ImageSource="Resources/Logo.png" Stretch="Uniform" />
        </Rectangle.Fill>

    </Rectangle>

这仍然会直接显示鼠标单击旁边的上下文菜单。如果我在上下文菜单代码中将Placement设置为bottom,而不是将ContextMenuService位添加到Rectangle,它会在相对于整个窗口的底部或顶部显示它。

任何帮助将不胜感激。谢谢!

编辑:我也在使用一种方法来启用左键单击矩形。在MouseDown上,它调用此方法:

    private void MenuClicked(object sender, System.Windows.RoutedEventArgs e)
    {
        Menu.PlacementTarget = this;
        Menu.IsOpen = true;
    }

1 个答案:

答案 0 :(得分:1)

您需要设置ContextMenuService.PlacementTarget属性,以便框架知道上下文菜单应该相对于哪个元素,例如:

<Rectangle x:Name="rectangle" ContextMenuService.PlacementTarget="{Binding RelativeSource={RelativeSource Self}}" ... />

只需将该属性添加到R​​ectangle声明中即可。与ContextMenuService.Placement="Bottom"结合使用时,上下文菜单将按预期显示在底部。

编辑:由于您以编程方式打开菜单,因此需要直接在菜单上设置PlacementPlacementTarget属性。来自ContextMenuService的附加属性,当在菜单所有者上设置时,仅在通过常规方式打开上下文菜单(例如,右键单击)时才会生效。在MouseDown处理程序中,您设置的是PlacementTarget = this;,但您应该设置PlacementTarget = rectangle;