【问题标题】:How to find whether button single clicked or double clicked while executing custom commands for button如何在执行按钮的自定义命令时查找按钮是单击还是双击
【发布时间】:2014-05-23 14:06:18
【问题描述】:

我的需求:我想为我的WPF按钮设置自定义命令,在自定义命令执行里面我想知道该命令是鼠标单击还是双击执行的。此外,当 customCommand 的 CanExecute 返回 false 时,我希望按钮进入禁用状态。详情请参阅下文。

说明: 嗨,在 WPF 中,我为按钮设置了自定义命令。当我单击按钮(单击和双击)时,命令将被执行。在自定义命令中,我想为单击和双击处理单独的操作。是否可以在命令中找到单击按钮或双击按钮?我使用.Net 4.0,c#4.0

注意:我提到了这个How to bind a command in WPF to a double click event handler of a control?,但我在这里遇到了限制。
局限性: 当我为按钮设置自定义命令时,在 CustomCommand CanExcute 返回 false 时,按钮进入禁用状态。但是根据上述建议,通过将命令设置为鼠标绑定并将鼠标绑定设置为按钮可以工作,但是当 CanExecute 返回 false 时,按钮不会进入禁用状态。如何克服这个

公共自定义命令:ICommandd { public bool CanExecute(对象参数) { //任意逻辑 }

public void Execute(object parameter)
{
    if(MouseSingleClick)
    {
        perform ActionA;
    }
    if(MouseDoubleClick)
    {
        PerformActionB;
    }
}

}

提前致谢。

【问题讨论】:

  • 它取决于单击鼠标的哪个按钮,或者您只想在左键单击或双击时触发事件?
  • 嗨@aks81,感谢您的关注。我想在单击和双击(鼠标左键)时启动自定义命令,但是在自定义命令中我想查找它是单击还是双击,所以如果是单击我执行一个操作,如果它是双击我执行另一个动作。如果您需要更多信息,请告诉我。

标签: wpf c#-4.0


【解决方案1】:

我能够使用 this 并对其进行调整,以便以 MVVM 友好的方式使用它。

我给出了一个使用 Cinch 框架的工作示例。

我锄头这有助于你提出开始的想法。

我的视图模型

public class MyViewModel : INotifyPropertyChanged
{

    private static DispatcherTimer myClickWaitTimer =
            new DispatcherTimer (
                    new TimeSpan (0, 0, 0, 0, 150),
                    DispatcherPriority.Background,
                    mouseWaitTimer_Tick,
                    Dispatcher.CurrentDispatcher);

    private static void mouseWaitTimer_Tick (object sender, EventArgs e)
    {
        myClickWaitTimer.Stop ();

        Debug.WriteLine ("Single Click Executed");//PerformActionA
    }

    public ICommand CinchSingleClickCommand { get; private set; }
    public ICommand CinchDoubleClickCommand { get; private set; }


    public MyViewModel ()
    {
        CinchSingleClickCommand = new SimpleCommand<object, EventToCommandArgs> (CanExecuteSingleCinch, ExecuteSingleCinch);
        CinchDoubleClickCommand = new SimpleCommand<object, EventToCommandArgs> (CanExecuteDoubleCinch, ExecuteDoubleCinch);
        myClickWaitTimer.Stop ();
    }

    private void ExecuteDoubleCinch (EventToCommandArgs obj)
    {
        if (obj.EventArgs is MouseEventArgs)
        {
            myClickWaitTimer.Stop ();
            Debug.WriteLine ("Double Click Executed");//PerformActionB
            var mouseEvent = obj.EventArgs as MouseEventArgs;
            mouseEvent.Handled = true;
        }
    }

    private bool CanExecuteDoubleCinch (object arg)
    {
        return true;
    }

    private void ExecuteSingleCinch (EventToCommandArgs obj)
    {
        if (!(obj.EventArgs is MouseEventArgs))
        {
            myClickWaitTimer.Start ();
            var mouseEvent = obj.EventArgs as RoutedEventArgs;
            mouseEvent.Handled = true;
        }
    }

    private bool CanExecuteSingleCinch (object arg)
    {
        return true;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged (string propertyName)
    {
        var pc = PropertyChanged;
        if (pc != null)
            pc (this, new PropertyChangedEventArgs (propertyName));
    }
}

您可以使用 TimeSpan 构造函数来设置您希望在单击和双击之间保持多少延迟。

观点

<Window x:Class="DataGridTesting.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:cinch="clr-namespace:Cinch;assembly=Cinch.WPF"
            Title="MainWindow"
            Height="350"
            Width="525">
<DockPanel>
    <Button x:Name="button"
                    Content="Test">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick">
                <cinch:EventToCommandTrigger Command="{Binding CinchDoubleClickCommand}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="Click">
                <cinch:EventToCommandTrigger Command="{Binding CinchSingleClickCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
</DockPanel>
</Window>

视图背后的代码

public partial class MainWindow : Window
{
    public MainWindow ()
    {
        InitializeComponent ();
        this.DataContext = new MyViewModel ();
    }
}

我使用 Nuget 包管理器为 CinchSystem.Windows.InteractivityMicrosoft.Expression.Interactions 提取所需的 dll

【讨论】:

  • 您可以将两个命令合二为一,并使用if 语句来区分单击和双击。仅出于验证目的,我将事件分为两个命令
  • @asks81 感谢您花时间为我服务。我正在尝试在我的项目中实现您的代码。我没有使用 cinch 框架。这可以在没有 cinch 组件的情况下完成吗??
  • 是的,你可以。只需从 Cinch 源代码中提取所需的代码。如果您需要帮助,请告诉我。我将尝试创建完整的相关代码。现在我不在办公室。明天我可以给出完整的代码。
  • 好吧,我会等你的样品,同时我会在我这边试试。
  • 我能够创建一个工作示例。代码很大,因为我必须将多个文件复制到解决方案中。所以我会在你的项目中提供你需要的必要文件夹。从 Cinch here 下载源代码并解压缩 zip。打开路径V2 (VS2010 WPF and SL)\CinchV2 并将文件夹CommandsEventsInteractivity 复制到您的解决方案中。修复命名空间,并将许可证文本文件保存在 cinch 文件夹中。然后你应该能够执行我在示例中给出的上述代码。
【解决方案2】:

令人困惑的是 Button 控件的默认单击事件会影响其他事件,例如双击、鼠标按下等。因此,使用标签可能是个好主意。您可以将其伪装成一个按钮,然后使用标签的 MouseDown 和 MouseDoubleClick 事件来执行您的两个不同任务。使用计时器来区分单击。以下链接显示更多详细信息

double click/ single click

【讨论】:

  • 嗨@voddy,在我的场景中使用标签作为按钮是不可行的。在我的项目中,我在按钮模板中使用标签和路径。
猜你喜欢
  • 2017-07-31
  • 2013-01-23
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
相关资源
最近更新 更多