【问题标题】:WPF left-click ContextMenu doesn't dissaepear on second clickWPF左键单击ContextMenu不会在第二次单击时消失
【发布时间】:2015-10-05 08:41:51
【问题描述】:

我已经为 WPF 按钮实现了一个新的行为,用于通过左键单击使用上下文菜单:

public class LeftClickContextMenuButtonBehavior : Behavior<Button>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.AddHandler(UIElement.MouseDownEvent, new RoutedEventHandler(AssociatedObject_MouseDown), true);
    }

    void AssociatedObject_MouseDown(object sender, RoutedEventArgs e)
    {
        Button source = sender as Button;
        if (source != null && source.ContextMenu != null)
        {
            source.ContextMenu.PlacementTarget = source;
            source.ContextMenu.Placement = PlacementMode.Bottom;
            source.ContextMenu.IsOpen = !source.ContextMenu.IsOpen;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.RemoveHandler(UIElement.MouseDownEvent, new RoutedEventHandler(AssociatedObject_MouseDown));
    }
}

XAML:

<Button Content="Left ContextMenu test">
    <i:Interaction.Behaviors>
        <extensions:LeftClickContextMenuButtonBehavior />
    </i:Interaction.Behaviors>
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Item A" />
            <MenuItem Header="Item B" /> 
        </ContextMenu>
    </Button.ContextMenu>
</Button>

它工作正常,但我有一个小问题 - 第二次单击按钮(在上下文菜单仍然打开期间),菜单关闭并立即重新打开,但预期的行为是关闭菜单 - @987654323 @。因此,似乎在触发 MoseDown on 按钮之前,其他一些功能会关闭菜单。如何避免?

【问题讨论】:

    标签: c# .net wpf xaml


    【解决方案1】:

    我想我找到了解决办法:

    <Button Content="Left ContextMenu test" IsHitTestVisible="{Binding ElementName=cm, Path=IsOpen, Mode=OneWay, Converter={StaticResource BoolInverter}}">
        <i:Interaction.Behaviors>
            <extensions:LeftClickContextMenuButtonBehavior />
        </i:Interaction.Behaviors>
        <Button.ContextMenu>
            <ContextMenu x:Name="cm">
                <MenuItem Header="Item A" />
                <MenuItem Header="Item B" /> 
            </ContextMenu>
        </Button.ContextMenu>
    </Button>
    

    其中 BoolInverterConverter 定义为:

     public class BoolInverter : IValueConverter
     {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         {
           if (value is bool)
             return !(bool)value;
           return value;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    

    这样当你第二次点击按钮时没有被点击但是上下文菜单会因为失去焦点而关闭。

    【讨论】:

    • 谢谢,但它仍然不起作用 - 似乎 ContextMenu.IsOpen 在 Button 检查 IsHitTestVisible 的值之前设置为 False。我认为,父窗口处理 MouseDown,关闭所有上下文菜单,然后将 MouseDown 事件路由到按钮,但当时上下文菜单已经关闭,所以 IsHitTestVisible=true 和 tegrefore 按钮处理 MouseDown 并重新打开菜单......
    • 我在一个小测试应用程序中尝试过这段代码,它运行良好。你能只试试这个例子吗?
    【解决方案2】:

    试试这个:

    void AssociatedObject_MouseDown(object sender, RoutedEventArgs e)
    {
        e.handled = true;  // handle the event
        Button source = sender as Button;
    
        //rest of the code ...
    }
    

    祝你好运!

    【讨论】:

    • 我认为这行不通。该问题与未处理的事件无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多