WPF: кнопка с одним щелчком мыши + двойной щелчок - PullRequest
15 голосов
/ 09 июня 2009

Мне приходится обрабатывать как одиночный, так и двойной щелчок кнопки в приложении WPF с различной реакцией. К сожалению, при двойном щелчке WPF запускает событие двух щелчков и событие двойного щелчка, поэтому трудно справиться с этой ситуацией.

Он пытался решить ее с помощью таймера, но безуспешно ... Надеюсь, вы мне поможете.

Давайте посмотрим код:

private void delayedBtnClick(object statInfo)
{
    if (doubleClickTimer != null)
        doubleClickTimer.Dispose();
    doubleClickTimer = null;

    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new VoidDelegate(delegate()
    {
        // ... DO THE SINGLE CLICK ACTION
    }));
}

private void btn_Click(object sender, RoutedEventArgs e)
{
    if (doubleClickTimer == null)
        doubleClickTimer = new Timer(delayedBtnClick, null, System.Windows.Forms.SystemInformation.DoubleClickTime, Timeout.Infinite);
        }
    }
}

private void btnNext_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    if (doubleClickTimer != null)
        doubleClickTimer.Change(Timeout.Infinite, Timeout.Infinite);    // disable it - I've tried it with and without this line
        doubleClickTimer.Dispose();
    doubleClickTimer = null;

    //.... DO THE DOUBLE CLICK ACTION
}

Проблема в том, что «ДЕЙСТВИЕ ОДНОГО ЩЕЛЧКА» вызывается после «ДВОЙНОГО ЩЕЛЧКА» при двойном щелчке Странно, что я установил значение doubleClickTimer в null при двойном щелчке, но в delayedBtnClick это правда: O

Я уже пытался использовать более длительное время, флаг bool и блокировку ...

У вас есть идеи?

Лучший!

Ответы [ 2 ]

16 голосов
/ 09 июня 2009

Если вы установите RoutedEvent e.Handled на true после обработки события MouseDoubleClick, то оно не будет вызывать событие Click во второй раз после MouseDoubleClick.

Существует недавняя запись , в которой говорится о различном поведении для SingleClick и DoubleClick, что может быть полезно.

Однако, если вы уверены, что хотите отдельное поведение и хотите / должны заблокировать первый Click, а также второй Click, вы можете использовать DispatcherTimer, как и раньше.

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

private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    // Stop the timer from ticking.
    myClickWaitTimer.Stop();

    Trace.WriteLine("Double Click");
    e.Handled = true;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    myClickWaitTimer.Start();
}

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

    // Handle Single Click Actions
    Trace.WriteLine("Single Click");
}
6 голосов
/ 09 июня 2009

Вы можете попробовать это:

Button.MouseLeftButtonDown += Button_MouseLeftButtonDown;

private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;

    if (e.ClickCount > 1)
    {
        // Do double-click code
    }

    else
    {
        // Do single-click code
    }
}

Если необходимо, вы можете потребовать щелчка мышью и подождать, пока мышь не поднимется, чтобы выполнить действие.

...