2015-10-05 65 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

相關問題