2016-12-13 7 views
0

Чтобы использовать клавиатуру как музыкальную клавиатуру - нажмите клавишу для воспроизведения, отпустите клавишу для остановки воспроизведения. Приложение UWP, а целевая платформа - Windows 10 с обычной клавиатурой hw. Я пытаюсь сделать это с помощью события Key_down. Вот тестовый код XAML (страница пуста, и только код C#):Как получить событие Key_down без повторения?

using System; 
using System.Diagnostics; 
using Windows.UI.Core; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Navigation; 

namespace testKeyborad 
{ 
    public sealed partial class MainPage : Page 
    { 
     public MainPage() 
     { 
      this.InitializeComponent(); 
     } 

     protected override void OnNavigatedTo(NavigationEventArgs e) 
     { 
      Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown; 
     } 

     protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) 
     { 
      Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown; 
     } 

     private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args) 
     { 
      Debug.WriteLine($"CoreWindow_KeyDown: {args.VirtualKey} {args.KeyStatus.WasKeyDown} {DateTime.Now:mm:ss.ss}"); 
     } 
    } 
} 

Когда я держу ключ, событие стрельбы неоднократно. Существует обходное решение с args.KeyStatus.WasKeyDown, которое является ложным в первом случае (это показано в коде), но это странный способ.

Можно ли получить только одно событие key_down?

+0

Возможно, у меня был только флаг, который срабатывает при нажатии на него и просто обрабатывает все будущие запросы на события. затем снимите флажок, когда ключ поднимается. – Takarii

+3

'args.KeyStatus.WasKeyDown' похоже на путь. Почему бы вам просто игнорировать любые события, которые имеют этот набор? –

+0

Вы можете усложниться и отделить событие от нажатия клавиш, затем он не будет запускаться снова и повторно подключить его к клавиатуре или использовать любое другое запутанное предложение, которое вы получите :) Но похоже, что 'WasKeyDown' предназначен для достижения того, что вы ищете почему бы не использовать его? – Nope

ответ

0

Как и было предложено, вы можете использовать флаг, кроме того, вы можете подавить нажатие клавиши, если этот флаг нажат, и использовать KeyUp для его сброса.

private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args) 
    { 
     if (KeyDown) 
     { 
      args.SuppressKeyPress = true; 
     } 
     else 
     { 
      Debug.WriteLine($"CoreWindow_KeyDown: {args.VirtualKey} {args.KeyStatus.WasKeyDown} {DateTime.Now:mm:ss.ss}"); 
      KeyDown = true; 
     } 
    } 

    public void CoreWindow_KeyUp(CoreWindow sender, KeyEventArgs args) 
    { 
     KeyDown = false; 
    } 
+0

это не будет работать так, как предполагалось. Если вы нажмете, давайте предположим, что 'A', а затем нажмите клавишу' B', тогда вы отпустите клавишу 'A', после освобождения' A' он уловит «A» и «B», но «B». –

0

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

public sealed partial class MainPage : Page 
    { 
     private Key _lastKeyPressed; 
     public MainPage() 
     { 
      this.InitializeComponent(); 
     } 

     protected override void OnNavigatedTo(NavigationEventArgs e) 
     { 
      Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown; 
     } 

     protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) 
     { 
      Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown; 
     } 

     private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args) 
     { 
      if(e.Key != _lastKeyPressed) 
      { 
       //do something 
       Debug.WriteLine($"CoreWindow_KeyDown: {args.VirtualKey} {args.KeyStatus.WasKeyDown} {DateTime.Now:mm:ss.ss}"); 
      } 
      _lastKeyPressed = e.Key; 
     } 
    }