2010-10-05 85 views
4

如何啓用鼠標綁定到右鍵釋放?目前,我在xaml中關聯了關閉wpf窗口的以下代碼。這裏的問題在於,因爲它在關閉窗口時對點擊的加速作出反應,所以激活了桌面上的上下文菜單。發佈WPF RightClick MouseBinding?

<MouseBinding Command="Close" MouseAction="RightClick" /> 
+1

Wouter - 您需要突出顯示您的代碼並將其定義爲代碼(單擊代碼圖標)以供其顯示。 – ChrisBD 2010-10-05 11:04:44

+0

在eventHandling的情況下,事件包含鼠標的狀態等。我猜在iCommands中沒有類似的東西。 – 2011-02-17 17:57:03

+0

你應該檢查手勢。 InputGestures,MouseGesures等。我確實認爲鼠標綁定有這樣的屬性。 – 2011-02-17 18:01:11

回答

8

MouseBinding不支持鼠標後續行動,只按下鼠標的動作,所以你根本就不是你想要使用MouseBinding做什麼做的。最簡單的替代方案是MouseRightButtonUp事件的代碼隱藏事件處理程序,您可以將MouseBinding作爲InputBinding添加到。但我懷疑你是出於你自己的原因避免了事件處理程序的方法,但是你應該澄清這是否是你的意圖。

可用的其他選項是某種形式的附加行爲。有很多方法可以做到這一點,但我會使用來自Blend行爲的相當標準的System.Windows.Interactivity。你所要做的就是附加鼠標右鍵的事件觸發器並調用close命令。您需要做的所有事情都在SDK中,但不幸的是,調用名爲InvokeCommandAction的命令的功能不能正確支持路由命令,因此我寫了一個名爲ExecuteCommand的替代方案。

下面是一些樣本標記:

<Grid Background="White"> 
    <Grid.CommandBindings> 
     <CommandBinding Command="Close" Executed="CommandBinding_Executed"/> 
    </Grid.CommandBindings> 
    <!--<Grid.InputBindings> 
     <MouseBinding Command="Close" MouseAction="RightClick"/> 
    </Grid.InputBindings>--> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseRightButtonUp"> 
      <utils:ExecuteCommand Command="Close"/> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <StackPanel> 
     <TextBox Text="Some Text"/> 
    </StackPanel> 
</Grid> 

你的老方法被註釋掉,新方法是在它下面。

這裏是後臺代碼只是掛鉤的路由命令:

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) 
    { 
     Close(); 
    } 

最後,這裏是ExecuteCommand實現:

public class ExecuteCommand : TriggerAction<DependencyObject> 
{ 
    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    public static readonly DependencyProperty CommandProperty = 
     DependencyProperty.Register("Command", typeof(ICommand), typeof(ExecuteCommand), null); 

    public object CommandParameter 
    { 
     get { return (object)GetValue(CommandParameterProperty); } 
     set { SetValue(CommandParameterProperty, value); } 
    } 

    public static readonly DependencyProperty CommandParameterProperty = 
     DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExecuteCommand), null); 

    public UIElement CommandTarget 
    { 
     get { return (UIElement)GetValue(CommandTargetProperty); } 
     set { SetValue(CommandTargetProperty, value); } 
    } 

    public static readonly DependencyProperty CommandTargetProperty = 
     DependencyProperty.Register("CommandTarget", typeof(UIElement), typeof(ExecuteCommand), null); 

    protected override void Invoke(object parameter) 
    { 
     if (Command is RoutedCommand) 
     { 
      var routedCommand = Command as RoutedCommand; 
      var commandTarget = CommandTarget ?? AssociatedObject as UIElement; 
      if (routedCommand.CanExecute(CommandParameter, commandTarget)) 
       routedCommand.Execute(CommandParameter, commandTarget); 
     } 
     else 
     { 
      if (Command.CanExecute(CommandParameter)) 
       Command.Execute(CommandParameter); 
     } 
    } 
} 

如果你不使用路由命令,但使用MVVM RelayCommand,你可以不需要ExecuteCommand,你可以使用InvokeCommandAction來代替。

本示例使用行爲。如果你不熟悉的行爲,安裝的Expression Blend 4 SDK,並添加這個命名空間:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 

,並添加System.Windows.Interactivity到您的項目。

+0

有趣的東西,我想我應該閱讀行爲! – Wouter 2011-02-21 08:42:40