2009-06-04 2 views
3

Рассмотрите следующий код, у меня есть текстовый блок, который является кнопкой «Вкл./Выкл.» В WPF. Это только текст внутри эллипса, который говорит ON/OFF. Когда пользователь нажимает кнопку и удерживает левую кнопку мыши в течение ОДНОЙ секунды, он будет выполнять код «включить устройство», если устройство еще не включено. Если пользователь удерживает кнопку ON/OFF в течение трех секунд или более (держит левую кнопку мыши HELD down), устройство выключится.WPF DispatcherTimer и кнопка мыши Нажмите Timing

Несколько проблем, с которыми мне не хватает лодку. 1. Событие тика не срабатывает при удерживании кнопки мыши, несмотря на то, что таймер запущен. 2. Цикл do/while никогда не выходит, несмотря на поднятие кнопки

Спасибо!

public int TimerCount = 0; 

    private void ButtonPressTimer(object sender, EventArgs e) 
    { 
     TimerCount = TimerCount + 1; 
    } 

    private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     var buttonPressTimer = new DispatcherTimer(new TimeSpan(0, 0, 0, 1), DispatcherPriority.Normal, ButtonPressTimer, this.Dispatcher); 

     do 
     { 
      if (!buttonPressTimer.IsEnabled) 
       buttonPressTimer.Start(); 
     } 
     while (e.ButtonState == MouseButtonState.Pressed); 

     buttonPressTimer.Stop(); 
     if (TimerCount >= 3) 
     { 
      //do something here 
     } 
     else 
     { 
      //do something different here 
     } 
    } 

ответ

5

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

private DateTime mousePressed; 

private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    mousePressed = DateTime.Now; 
} 

private void txtBlockOnOff_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{ 
    // button released 

    TimeSpan difference = DateTime.Now - mousePressed; 

    if (difference.TotalSeconds >= 3) 
    { 
     // long press 
    } 
    else 
    { 
     // short press 
    } 
} 
+0

Кстати, ваши требования говорят, что короткое нажатие составляет 1 секунду, а длительное нажатие - 3 секунды, но это не то, что отражено в коде. Как и ваш оригинал, мой пример предполагает, что длительное нажатие - это что-то более 3 секунд, а короткое нажатие - что-то меньшее. Изменение этого было бы легко с использованием кода, который я опубликовал, поскольку вы можете получить как можно более конкретную информацию, сравнивая с TimeSpan. –

1

Вы застреваете в цикле - диспетчерские таймеры запускаются в том же потоке, но вы заняты застреванием в обработчике Clicked.

Редактировать: Подумайте об этом - как кто-нибудь изменит флаг MousePressed? Существует только один поток (хорошо технически, два, но помните это как один!) Если вы блокируете в обработчике, WPF не может сделать что-нибудь.

3

Я считаю, что ответом на этот вопрос является использование RepeatButton, который выполняет именно то, что вам нужно, то есть он продолжает запускать событие, пока вы не отпустите кнопку.

Смежные вопросы