WPF单击鼠标右键MouseBinding上发布? [英] WPF RightClick MouseBinding on release?

查看:987
本文介绍了WPF单击鼠标右键MouseBinding上发布?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能使鼠标结合右键释放?此刻我在XAML以下code这是与关闭WPF窗口。这里的问题是,由于它在关闭窗口时反作用于点击的rampup它激活在桌面上的上下文菜单。

 < MouseBinding命令=关闭MouseAction =单击鼠标右键/>


解决方案

MouseBinding 不支持鼠标的后续行动,只按下鼠标的动作,所以你根本无法做什么你想使用 MouseBinding 做的。最简单的办法是在同一个元素上的的MouseRightButtonUp 事件中,你将增加一个code-背后的事件处理程序 MouseBinding InputBinding 来。但我怀疑你是避免了你自己的原因的事件处理程序的办法,但你应该清楚,如果这是你的意图。

可使用剩下的选择是某种形式的附加行为。有很多方法可以做到这一点,但我会用相当标准 System.Windows.Interactivity 从混合的行为。所有你需要做的就是附加一个事件触发鼠标右键,并调用close命令。你需要做的这一切都是在SDK但遗憾的是该功能调用一个叫做命令 InvokeCommandAction 不能正确支持路由命令,所以我写了所谓的替代 ExecuteCommand

下面是一些样本标记:

 <网格背景=白>
    < Grid.CommandBindings>
        <命令的CommandBinding =关闭时,执行=CommandBinding_Executed/>
    < /Grid.CommandBindings>
    <! - < Grid.InputBindings>
        < MouseBinding命令=关闭MouseAction =单击鼠标右键/>
    < /Grid.InputBindings> - >
    < I:Interaction.Triggers>
        < I:的EventTrigger事件名称=的MouseRightButtonUp>
            < utils的:ExecuteCommand命令=关闭/>
        < /我:&的EventTrigger GT;
    < /我:Interaction.Triggers>
    <&StackPanel的GT;
        <文本框的文本=一些文本/>
    < / StackPanel的>
< /网格和GT;

您老方法被注释掉,新方法是在它下面。

下面是code-仅仅落后挂钩的路由命令:

 私人无效CommandBinding_Executed(对象发件人,ExecutedRoutedEventArgs E)
    {
        关();
    }

最后,这里是实施 ExecuteCommand

 公共类ExecuteCommand:TriggerAction<&的DependencyObject GT;
{
    公共ICommand的命令
    {
        {返回(的ICommand)的GetValue(CommandProperty); }
        集合{的SetValue(CommandProperty,值); }
    }    公共静态只读的DependencyProperty CommandProperty =
        DependencyProperty.Register(命令中的typeof(ICommand的)的typeof(ExecuteCommand),NULL);    公共对象CommandParameter
    {
        {返回(对象)的GetValue(CommandParameterProperty); }
        集合{的SetValue(CommandParameterProperty,值); }
    }    公共静态只读的DependencyProperty CommandParameterProperty =
        DependencyProperty.Register(CommandParameter的typeof(对象)的typeof(ExecuteCommand),NULL);    公众的UIElement CommandTarget
    {
        {返回(的UIElement)的GetValue(CommandTargetProperty); }
        集合{的SetValue(CommandTargetProperty,值); }
    }    公共静态只读的DependencyProperty CommandTargetProperty =
        DependencyProperty.Register(CommandTarget的typeof(的UIElement)的typeof(ExecuteCommand),NULL);    保护覆盖无效调用(对象参数)
    {
        如果(司令部的RoutedCommand)
        {
            VAR的RoutedCommand =命令的RoutedCommand;
            VAR commandTarget = CommandTarget?作为AssociatedObject中的UIElement;
            如果(routedCommand.CanExecute(CommandParameter,commandTarget))
                routedCommand.Execute(CommandParameter,commandTarget);
        }
        其他
        {
            如果(Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        }
    }
}

如果你不使用路由命令,但使用的是说,一个MVVM RelayCommand,你可以不需要 ExecuteCommand ,你可以使用 InvokeCommandAction 来代替。

本例使用的行为。如果你不熟悉的行为,安装防爆pression混合4 SDK并添加此命名空间:

 的xmlns:I =htt​​p://schemas.microsoft.com/ex$p$pssion/2010/interactivity

System.Windows.Interactivity 添加到项目中。

How can I enable a mouse binding to the release of the right button? At the moment I have the following code in xaml which is linked to closing the wpf window. The problem here is that because it reacts to the rampup of the click when closing the window it activates a context menu on the desktop.

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

解决方案

The MouseBinding does not support mouse up actions, only mouse down actions, so you simply cannot do what you want to do using a MouseBinding. The simplest alternative is a code-behind event handler for the MouseRightButtonUp event on the same element you would have added the MouseBinding as an InputBinding to. But I suspect you are avoiding the event handler approach for your own reasons, but you should clarify if that is your intention.

The remaining option available to use is some form of attached behavior. There are many ways to do this but I'll use the fairly standard System.Windows.Interactivity from Blend behaviors. All you have to do is attach an event trigger for right mouse button up and invoke the close command. Everything you need to do this is in the SDK but unfortunately the feature to invoke a command called InvokeCommandAction doesn't properly support routed commands so I've written an alternative called ExecuteCommand.

Here is some sample markup:

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

Your old method is commented out and the new method is below it.

Here is the code-behind just to hook up the routed command:

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

Finally, here is the implementation of 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);
        }
    }
}

If you are not using routed commands but are using say, an MVVM RelayCommand, you can don't need ExecuteCommand and you can use InvokeCommandAction instead.

This example uses behaviors. If you are not familiar with behaviors, install the Expression Blend 4 SDK and add this namespace:

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

and add System.Windows.Interactivity to your project.

这篇关于WPF单击鼠标右键MouseBinding上发布?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆