1

我正在使用 WPF 和 MVVM 模拟手持设备(viewmodel 是状态机,view 是带有按钮的模拟塑料外壳)。

打开和关闭设备的手势是按钮中的“长按”。例如,在使用过程中,如果我按下“确定”按钮,它会显示一些屏幕,但如果我按住它点击超过三秒钟,它应该(以模拟方式)关闭设备。

我查看RepeatButton了它的DelayInterval属性,但它们似乎触发了相同的Click事件。Click如果我按住按钮不到三秒钟,我需要的是触发一个常规,如果我按住它超过三秒钟,则触发另一个不同的LongClick(可能一次)。

我怎样才能做到这一点,使用 RepeatButton 甚至是普通的 Button?

4

2 回答 2

3

您可以这样做的一种方法是绑定到 MouseDown 和 MouseUp 事件。使用在 MouseDown 上启动的秒表之类的东西,并检查在 MouseUp 上经过的时间量。如果少于 3 秒,请执行 Click() 操作。如果超过 3 秒,请执行 LongClick() 操作。

private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    stopwatch = new Stopwatch();
    stopwatch.Start();
}

private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    stopwatch.Stop();

    if (stopwatch.ElapsedMilliseconds >= 3000)
    {
         // do Click()
    }
    else
    {
        // do LongClick
    }
}

这是RepeatButton的解决方案:

private bool isLongClick;
private bool hasAlreadyLongClicked;
private void RepeatButton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    isLongClick = false;
    hasAlreadyLongClicked = false;
    stopwatch = new Stopwatch();
    stopwatch.Start();
}

private void RepeatButton_Click(object sender, RoutedEventArgs e)
{
    if (!hasAlreadyLongClicked && stopwatch.ElapsedMilliseconds >= 3000)
    {
        hasAlreadyLongClicked = true;
        isLongClick = true;
        // do your LongClick action
    }
}

private void RepeatButton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    if (!isLongClick)
    {
        // do short click action
    }
}

这里的诀窍是,RepeatButton 基本上只是一个在每个间隔触发 Click 的 Button。因此,如果我们在 PreviewMouseDown 上为按钮启动秒表,我们可以在每次 Click 事件触发时检查秒表上的经过时间,并根据结果修改我们的操作。

于 2014-10-31T20:19:15.550 回答
0

经过一个周末的冥想,我设计了以下可行的解决方案:

  1. 在 ViewModel 中创建两个布尔标志:ClickedShortClickedLong;
  2. Command通过命令将按钮上的属性绑定到OKViewModel 上的方法;
  3. OK 命令是这样的:

    public void OK()
    {
        if (!ClickedShort)
        {
            HandleShortClick();
            ClickedShort = true;
        }
        else if (!ClickedLong)
        {
            HandleLongClick();
            ClickedLong = true;
        }
    }    
    
  4. 在 XAML 中有两个 CheckBox,其IsChecked属性绑定到布尔标志。这些只是中继,因此我可以通过绑定将信息从 View 发送到 ViewModel:

        <CheckBox x:Name="ClickedShort" IsChecked="{Binding ClickedShort, Mode=OneWayToSource}" Visibility="Collapsed"/>
        <CheckBox x:Name="ClickedLong" IsChecked="{Binding ClickedLong, Mode=OneWayToSource}" Visibility="Collapsed"/>
    
  5. 当我释放按钮时,在 OK 按钮中有一个MouseUp事件将这些标志重置为 false。

于 2014-11-03T13:27:30.067 回答