2015-10-05 66 views
1

dissaepear我实现了WPF按钮,一个新的行为使用上下文菜单左键点击: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> 

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

回答

0

试试这个:

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

    //rest of the code ... 
} 

祝您好运!

+0

我不认为这会奏效。问题与未处理的事件无关。 – Giangregorio

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(); 
    } 
    } 

这样,当你点击按钮第二次没有点击,但上下文菜单将关闭,因为它失去了焦点。

+0

谢谢,但它仍然不起作用 - 看起来,在Button检查IsHitTestVisible的vaue之前ContextMenu.IsOpen被设置为False。我认为,父窗口处理MouseDown,关闭所有上下文菜单,然后将MouseDown事件发送到按钮,但是此时上下文菜单已关闭,因此IsHitTestVisible = true,tegrefore按钮处理MouseDown并重新打开菜单... –

+0

我曾在一个小测试应用程序中试过这段代码,它运行良好。你能试试这个例子吗? – Giangregorio

相关问题