【问题标题】:wpf context menu left-clickwpf上下文菜单左键单击
【发布时间】:2012-07-16 22:10:03
【问题描述】:

是否可以将上下文菜单附加到 wpf 控件并在左键单击时打开它(而不是更习惯的右键单击)?我想仅使用 xaml 来实现(这应该是我的控件视图模板的一部分)。

【问题讨论】:

    标签: c# wpf user-interface contextmenu


    【解决方案1】:

    这是一种在左键单击时显示上下文菜单的方法:

    在Border 元素上创建一个新的左键处理程序:

    <Border x:Name="Win"
            Width="40"
            Height="40"
            Background="Purple"
            MouseLeftButtonUp="UIElement_OnMouseLeftButtonUp">
    

    然后添加:

    private void UIElement_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
    
        var mouseDownEvent =
            new MouseButtonEventArgs(Mouse.PrimaryDevice,
                Environment.TickCount,
                MouseButton.Right)
            {
                RoutedEvent = Mouse.MouseUpEvent,
                Source = Win,
            };
    
    
        InputManager.Current.ProcessInput(mouseDownEvent);
    }
    

    它的作用,它基本上将左键单击映射到右键单击。为了可重用性,您可以将其包装到附加的行为中。

    【讨论】:

    • 谢谢,这是我发现的唯一符合您在 ContextMenuService.Placement... 属性中指定的解决方案。
    【解决方案2】:

    下面是我建议的一个简单示例:

    XAML:

    <Window x:Class="LeftClickMenu.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow">
        <Grid>
            <Border Width="400" Height="300" Background="#ccc" BorderBrush="#333" 
                    BorderThickness="1"
                    MouseLeftButtonDown="Border_MouseLeftButtonDown"
                    MouseRightButtonUp="Border_MouseRightButtonUp">
                <Border.ContextMenu>
                    <ContextMenu x:Name="myContextMenu">
                        <MenuItem Header="Menu Item 1" />
                        <MenuItem Header="Menu Item 2" />
                        <MenuItem Header="Menu Item 3" />
                        <MenuItem Header="Menu Item 4" />
                        <MenuItem Header="Menu Item 5" />
                    </ContextMenu>
                </Border.ContextMenu>
            </Border>
        </Grid>
    </Window>
    

    还有代码隐藏:

    using System.Windows;
    using System.Windows.Input;
    
    namespace LeftClickMenu
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                myContextMenu.IsOpen = true;
            }
    
            private void Border_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
            {
                e.Handled = true;
            }
        }
    }
    

    我还添加了额外的 MouseRightButtonUp 事件来禁止右键单击上下文菜单弹出。

    【讨论】:

    • (抱歉回复晚了。)但是我如何将这种行为转变为样式(例如在 Generic.xml 中)。正如我之前的评论中所指出的,我收到“错误 MC4007:无法在样式中的目标标签上指定事件 'MouseUp'。请改用 EventSetter。”
    • 我同意这个错误。您应该使用事件设置器。我不相信有一种有效的方法可以在样式中做到这一点,因为您需要它发生在特定事件中。
    【解决方案3】:
    1. 创建一个以编程方式打开子菜单的方法,如这篇 SO 文章中所述: Show menu programmatically in WPF

    2. 为 LeftMouseButtonDown 创建一个事件并在 XAML 中调用该事件。

    【讨论】:

    • 从代码中做这件事不会违反视图和逻辑之间的分离吗?对我来说,这部分属于视图(因此应在 xaml 中指定)。
    • 这是视图的代码隐藏,它是视图的一部分。您指的是在 ViewModel 中实现此代码,我根本不建议这样做。
    • 好吧,就这样吧。但是,我仍然不明白“为 LeftMouseButtonDown 创建一个事件并调用该方法”部分。我在 Generic.xaml 中有我的控件样式。我希望在单击以这种样式定义的控件之一时显示上下文菜单,例如。图像控制。所以我尝试将 MouseUp="method" 添加到 Image 标签,但我得到:错误 MC4007:无法在 Style 中的 Target 标签上指定事件“MouseUp”。请改用 EventSetter。如何从样式中连接事件处理程序?我的方法应该放在哪里? Generic.xaml.cs?
    • 我将样本放在单独的答案中。
    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多