C# 如何在WPF中显示按键移动?

C# 如何在WPF中显示按键移动?,c#,wpf,events,C#,Wpf,Events,我有这个方法,, 我需要应用程序等待,直到通过移动方法在gui中显示动作 我怎么做到的 void move (char c) { if (c == 't' || c == 'k') { KeyEventArgs e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Down) { RoutedEvent =

我有这个方法,, 我需要应用程序等待,直到通过移动方法在gui中显示动作 我怎么做到的

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();
    }

您可以让操作线程在键盘运行时对其进行采样,然后对按下的内容而不是事件执行操作

使用事件在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>
动作定义为

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;
    }
}
公共类VM:BindableBase
{
公共虚拟机()
{
SetAction=newdelegateCommand(a=>Action=a??GameAction.None);
}
私有字符串_ActionText;
公共字符串ActionText
{
获取{return\u ActionText;}
set{SetProperty(ref _ActionText,value);}
}
private bool_Running=false;
公营学校
{
获取{return\u Running;}
设置
{
if(SetProperty(ref _Running,value))
{
如果(正在运行)
StartGame();
}
}
}
公共游戏动作动作{get;set;}
公共DelegateCommand SetAction{get;set;}
公共任务ActionThread{get;set;}
公共无效StartName()
{
if(ActionThread==null)
{
ActionThread=Task.Run((Action)GameLoop);
}
}
公共异步void GameLoop()
{
(跑步时)
{
开关(动作)
{
case GameAction.MoveUp:
ActionText+=$“{DateTime.Now.ToLongTimeString()}Up”;
打破
case GameAction.MoveDown:
ActionText+=$“{DateTime.Now.ToLongTimeString()}向下”;
打破
case GameAction.Moveleft:
ActionText+=$“{DateTime.Now.ToLongTimeString()}左”;
打破
case GameAction.MoveRight:
ActionText+=$“{DateTime.Now.ToLongTimeString()}右”;
打破
违约:
ActionText+=$“{DateTime.Now.ToLongTimeString()}无移动”;
打破
}
等待任务。延迟(2000);//等待2秒
}
ActionThread=null;
}
}
注意:使用Prism时,我尝试了Sleep()和定时器,但没有工作
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;
    }
}