秒表没有停止

时间:2013-08-23 10:05:34

标签: wpf c#-4.0 wpf-controls dispatchertimer

我想控制用户在单击鼠标时单击还是双击。所以我使用这段代码:

private void MouseSingleClickCommand(RoutedEventArgs e)
{
    _dtMouseClick.Start();
}


private void MouseClick_Tick(object sender, System.EventArgs e)
{
    _dtMouseClick.Stop();

    //my one click code
}



private void MouseDoubleClickCommand(MouseButtonEventArgs e)
{
    _dtMouseClick.Stop();
    //code of the double click
}

_dt是在视图模型的构造函数中创建的DispatcherTimer:

_dtMouseClick =
                new System.Windows.Threading.DispatcherTimer(
                new TimeSpan(0, 0, 0, 0, 200),
                System.Windows.Threading.DispatcherPriority.Background,
                MouseClick_Tick,
                System.Windows.Threading.Dispatcher.CurrentDispatcher);

但是,始终执行一次单击代码,因为调度程序未停止。

为什么?

感谢。

编辑:我包含按钮的axml:

<StackPanel Height="Auto" HorizontalAlignment="Left" Margin="548,0,0,0" Name="stpBotnoesBasicos" VerticalAlignment="Top" Width="Auto">
                    <Button Content="Buscar" Height="23" Name="btn01" Width="75">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <cmd:EventToCommand Command="{Binding MouseSingleClickCommand}" PassEventArgsToCommand="True"/>
                            </i:EventTrigger>

                                <i:EventTrigger EventName="MouseDoubleClick">
                                <cmd:EventToCommand Command="{Binding MouseDoubleClickCommand}" PassEventArgsToCommand="True"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                    </Button>
</Stackpannel>

2 个答案:

答案 0 :(得分:1)

您在第一个勾选后停止它(_dtMouseClick.Stop();下的MouseClick_Tick)。请尝试以下更改以获得更清晰的图片:

private void MouseClick_Tick(object sender, System.EventArgs e)
{
    MessageBox.Show("One tick more");
}

并将Interval更改为1秒(new TimeSpan(0, 0, 0, 0, 1000))。

现在,MessageBox每秒弹出一次,直到双击(MouseDoubleClickCommand被调用)。在MouseClick_Tick内,您必须定期触发代码,而不是避免Timer运行的代码。

澄清

计时器必须使用的预期方式包括三个部分:START,DO ANYTHING(在_tick事件上),一旦它不再有用就停止。例如,如何注册点击次数?

Int clicksCounter = 0; //Declared globally.

您存储所需信息(点击次数);并在需要时启动计时器。

private void MouseLeftButtonDownCommand(MouseButtonEventArgs e)
{
     clicksCounter = clicksCounter + 1;
     if (clicksCounter == 1)
     {
         _dtMouseClick.Start(); //(set a small enough interval: 50ms or 10ms or even 1ms).
     }
}

现在你必须从_Tick方法检查目标变量的值(可以在需要时自行停止),即:

private void MouseClick_Tick(object sender, System.EventArgs e)
{
   //This event should be called as quickly as possible in order to check clicks at any time
    if(clicksCounter >= 2)
    {
        //Condition met. Reset the variables
        clicksCounter = 0;
        _dtMouseClick.Stop(); 
       MessageBox.Show("The user has clicked the mouse button more than once");
    }
}

答案 1 :(得分:0)

此解决方案基于另一个问题的解决方案:

base solution

如果我使用PreviewMouseLeftButtonDown控制何时单击或双击工作,而不是使用两个事件(单击和双击)。

所以我用这段代码解决了这个问题:

第一种方法用鼠标控制点击。

private void MouseLeftButtonDownCommand(MouseButtonEventArgs e)
        {

            if (e.ClickCount == 1)
            {
                _dtMouseClick.Start();
            }

            else if(e.ClickCount > 1)
            {
                _dtMouseClick.Stop();

                //the code of the double click
            }
        }

此方法是链接到DispatcherTimer的方法,如果第二次单击鼠标时没有停止,则执行该方法。

private void MouseClick_Tick(object sender, System.EventArgs e)
        {
            _dtrMouseClick.Stop();

            //code of the single click                
        }

dispatcherTimer是在视图模型

的构造函数中创建的
_dtBotonBuscarMouseClick =
                new System.Windows.Threading.DispatcherTimer(
                new TimeSpan(0, 0, 0, 0, 250),
                System.Windows.Threading.DispatcherPriority.Background,
                MouseClick_Tick,
                System.Windows.Threading.Dispatcher.CurrentDispatcher);
            _dtMouseClick.Stop();

间隔为250毫秒,即用户必须双击的时间间隔。

在这个解决方案中,我使用相同的方法来停止dispatcherTimer,stop()方法,但由于某种原因,如果我使用这两个事件(click和mouseDoubleClick),则双击中不会停止dispatcherTimer,如果我使用MouseLeftButtonDown事件,解决方案可以正常工作。

修改

这个解决方案适用于我的工作。

在MouseLeftButtonDown事件中,我检查ClickCount是1还是2.如果计数是1,那么我启动计时器。因此,如果之前没有停止,计时器将执行其代码。

如果第二次点击是双击,计时器将停止。这是ClickCounter&gt; 1.如果点击之间的失效时间足够大,则clickcounter始终为1,因此此事件MouseLeftButtonDown控制何时双击。

当执行计时器时,首先我停止它,因为我想要将其代码一次完成,只需单击一下我想要的代码。

如果我双击,那么我会在达到间隔之前停止计时器,所以永远不要执行,并在双击时执行我想要的代码。