void move (char c)
{
if (c == 't' || c == 'k')
{
KeyEventArgs e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Down) { RoutedEvent = Keyboard.KeyDownEvent };
InputManager.Current.ProcessInput(e1);
}
else if (c == 'l')
{
KeyEventArgs e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Left) { RoutedEvent = Keyboard.KeyDownEvent };
InputManager.Current.ProcessInput(e1);
}
else if (c == 'r')
{
KeyEventArgs e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Right) { RoutedEvent = Keyboard.KeyDownEvent };
InputManager.Current.ProcessInput(e1);
}
//System.Threading.Thread.Sleep(1000);
Timer.Stop();
}
答案 0 :(得分:0)
你要么让你的动作线程在运行时对键盘进行采样,然后对按下的内容采取行动而不是对事件采取行动
或
使用您的事件在您的VM上设置待处理操作标志,然后让您的操作线程将其用作输入而不是键盘
这是这种方法的一个例子
按下复选框后,此应用程序将每隔2秒将您的操作写入屏幕
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_ScratchPad"
xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
x:Class="WPF_ScratchPad.MainWindow"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525" KeyUp="Window_KeyUp">
<Window.DataContext>
<local:VM/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Gesture="Up" Command="{Binding SetAction}" >
<KeyBinding.CommandParameter>
<local:GameAction>MoveUp</local:GameAction>
</KeyBinding.CommandParameter>
</KeyBinding>
<KeyBinding Gesture="Down" Command="{Binding SetAction}" >
<KeyBinding.CommandParameter>
<local:GameAction>MoveDown</local:GameAction>
</KeyBinding.CommandParameter>
</KeyBinding>
<KeyBinding Gesture="Left" Command="{Binding SetAction}" >
<KeyBinding.CommandParameter>
<local:GameAction>MoveLeft</local:GameAction>
</KeyBinding.CommandParameter>
</KeyBinding>
<KeyBinding Gesture="Right" Command="{Binding SetAction}" >
<KeyBinding.CommandParameter>
<local:GameAction>MoveRight</local:GameAction>
</KeyBinding.CommandParameter>
</KeyBinding>
</Window.InputBindings>
<StackPanel>
<CheckBox IsChecked="{Binding Running}"/>
<TextBlock Text="{Binding ActionText}" TextWrapping="Wrap"/>
</StackPanel>
</Window>
背后的代码
private void Window_KeyUp(object sender, KeyEventArgs e)
{
(DataContext as VM).Action = GameAction.None;
}
操作定义为
public enum GameAction
{
None,
MoveUp,
MoveDown,
Moveleft,
MoveRight,
}
和ViewModel为
public class VM:BindableBase
{
public VM()
{
SetAction = new DelegateCommand<GameAction?>(a => Action = a ?? GameAction.None);
}
private string _ActionText;
public string ActionText
{
get { return _ActionText; }
set { SetProperty(ref _ActionText, value); }
}
private bool _Running = false;
public bool Running
{
get { return _Running; }
set
{
if(SetProperty(ref _Running, value))
{
if (Running)
StartGame();
}
}
}
public GameAction Action { get; set; }
public DelegateCommand<GameAction?> SetAction { get; set; }
public Task ActionThread { get; set; }
public void StartGame()
{
if (ActionThread == null)
{
ActionThread = Task.Run((Action) GameLoop);
}
}
public async void GameLoop ()
{
while(Running)
{
switch (Action)
{
case GameAction.MoveUp:
ActionText += $"{DateTime.Now.ToLongTimeString()} Up";
break;
case GameAction.MoveDown:
ActionText += $"{DateTime.Now.ToLongTimeString()} Down";
break;
case GameAction.Moveleft:
ActionText += $"{DateTime.Now.ToLongTimeString()} Left";
break;
case GameAction.MoveRight:
ActionText += $"{DateTime.Now.ToLongTimeString()} Right";
break;
default:
ActionText += $"{DateTime.Now.ToLongTimeString()} No Move";
break;
}
await Task.Delay(2000);//wait 2 seconds
}
ActionThread = null;
}
}
注意使用棱镜