C# WPF:轮询键盘
我正在开发一个在嵌入式设备上运行的WPF应用程序(.NET Standard 4 for embedded)。它附带了一大堆硬件,在我测试时会遇到阻碍,所以我创建了一个DummyHardware接口,当我运行单元测试或在我的开发PC上独立运行时,它除了打印日志消息之外什么都不做 到目前为止还不错。但是:该设备有一个4键键盘,可以进行轮询。我的虚拟键盘类在等待按键时进入无限循环,因为没有按键可按:-),所以我想,“好吧,我会轮询键盘,看看是按了1、2、3还是4”。但我有个例外 调用线程必须是STA 当我调用C# WPF:轮询键盘,c#,wpf,multithreading,C#,Wpf,Multithreading,我正在开发一个在嵌入式设备上运行的WPF应用程序(.NET Standard 4 for embedded)。它附带了一大堆硬件,在我测试时会遇到阻碍,所以我创建了一个DummyHardware接口,当我运行单元测试或在我的开发PC上独立运行时,它除了打印日志消息之外什么都不做 到目前为止还不错。但是:该设备有一个4键键盘,可以进行轮询。我的虚拟键盘类在等待按键时进入无限循环,因为没有按键可按:-),所以我想,“好吧,我会轮询键盘,看看是按了1、2、3还是4”。但我有个例外 调用线程必须是STA
Keyboard.IsKeyDown(Key.D1)
时。键盘轮询在一个单独的线程中进行(与硬件其余部分通常较慢的串行通信分离)。关于如何进行有什么想法吗?调用
注意:一种替代方法是跳过虚拟硬件上的“等待键”测试,但我不知道按下了哪个键,并且依赖它的以下代码将无法正常工作。Yuk.您可以将ApartmentState设置为STA。使用Thread.SetApartmentState方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace staThread
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Thread keyboardThread;
public MainWindow()
{
InitializeComponent();
keyboardThread = new Thread(new ThreadStart(KeyboardThread));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while (true)
{
if (Keyboard.IsKeyDown(Key.A))
{
}
Thread.Sleep(100);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间线程
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
线程键盘线程;
公共主窗口()
{
初始化组件();
键盘线程=新线程(新线程开始(键盘线程));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while(true)
{
如果(键盘.IsKeyDown(键.A))
{
}
睡眠(100);
}
}
}
}
您只需将ApartmentState设置为STA即可。使用Thread.SetApartmentState方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace staThread
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Thread keyboardThread;
public MainWindow()
{
InitializeComponent();
keyboardThread = new Thread(new ThreadStart(KeyboardThread));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while (true)
{
if (Keyboard.IsKeyDown(Key.A))
{
}
Thread.Sleep(100);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间线程
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
线程键盘线程;
公共主窗口()
{
初始化组件();
键盘线程=新线程(新线程开始(键盘线程));
keyboardThread.SetApartmentState(ApartmentState.STA);
keyboardThread.Start();
}
void KeyboardThread()
{
while(true)
{
如果(键盘.IsKeyDown(键.A))
{
}
睡眠(100);
}
}
}
}
我有一个简单的方法来处理在UI线程上运行的问题:
public object RunOnUiThread(Delegate method)
{
return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
其中,使用UI线程中的Dispatcher.CurrentDispatcher
初始化Dispatcher
。它可以从任何线程调用,使用方式如下:
UiThreadManager.RunOnUiThread((Action)delegate
{
// running on the UI thread
});
我有一个简单的方法来处理在UI线程上运行的问题:
public object RunOnUiThread(Delegate method)
{
return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
其中,使用UI线程中的Dispatcher.CurrentDispatcher
初始化Dispatcher
。它可以从任何线程调用,使用方式如下:
UiThreadManager.RunOnUiThread((Action)delegate
{
// running on the UI thread
});
谢谢安迪,我喜欢解决方案如此简单的时候:-)谢谢安迪,我喜欢解决方案如此简单的时候:-)