Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF左键单击上下文菜单不';不要在第二次单击时松开_C#_.net_Wpf_Xaml - Fatal编程技术网

C# WPF左键单击上下文菜单不';不要在第二次单击时松开

C# WPF左键单击上下文菜单不';不要在第二次单击时松开,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我已经为WPF按钮实现了一个新的行为,用于通过左键单击使用上下文菜单: public class LeftClickContextMenuButtonBehavior : Behavior<Button> { protected override void OnAttached() { base.OnAttached(); AssociatedObject.AddHandler(UIElement.MouseDownEvent, new

我已经为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));
    }
}
public类LeftClickContextMenuButtonBehavior:Behavior
{
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.AddHandler(UIElement.MouseDownEvent,新RoutedEventHandler(AssociatedObject_MouseDown),true);
}
无效关联对象\u鼠标向下(对象发送方,路由目标)
{
按钮源=发送方为按钮;
if(source!=null&&source.ContextMenu!=null)
{
source.ContextMenu.PlacementTarget=source;
source.ContextMenu.Placement=PlacementMode.Bottom;
source.ContextMenu.IsOpen=!source.ContextMenu.IsOpen;
}
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
RemoveHandler(UIElement.MousedowEvent,新RoutedEventHandler(AssociatedObject_MouseDown));
}
}
XAML:


它工作正常,但我有一个小问题-在第二次单击按钮时(上下文菜单仍然打开),菜单关闭并立即重新打开,但预期的行为是关闭菜单-
source.ContextMenu.IsOpen=!source.ContextMenu.IsOpen。因此,似乎在MoseDown on按钮启动之前,其他功能会关闭菜单。如何避免这种情况?

试试以下方法:

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

    //rest of the code ...
}

祝你好运

我想我找到了一个解决方案:

<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>

这样,当您第二次单击按钮时,不会单击,但上下文菜单将关闭,因为它失去焦点。

我认为这不起作用。此问题与未处理的事件无关。谢谢,但它仍然不起作用-在按钮检查IshitteVisible的值之前,ContextMenu.IsOpen似乎已设置为False。我认为,父窗口处理MouseDown,关闭所有上下文菜单,然后将MouseDown事件路由到按钮,但当时上下文菜单已经关闭,所以ishitestvisible=true和tegrefore按钮处理MouseDown并重新打开菜单……我在一个小测试应用程序中尝试了这段代码,效果很好。你能试一下这个例子吗?
<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>
 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();
    }
  }