Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过WPF中的接口引发键盘事件_C#_Wpf_Routed Events - Fatal编程技术网

C# 通过WPF中的接口引发键盘事件

C# 通过WPF中的接口引发键盘事件,c#,wpf,routed-events,C#,Wpf,Routed Events,我试图在WPF中构建一个应用程序,在这里我想处理连接到一台计算机的多个键盘的输入(按键事件)。因此,我有一个类,在这个类中我重写了WndProc()方法,并且能够从不同的键盘设备接收输入。在执行此操作时,我使用MainWindow句柄注册该类,因此该窗口可以接收CLR键盘事件。但这不是问题 问题是,现在我正在WPF中开发UserControl,它也可以响应这些多键盘事件。这些UserControls将在同一窗口中实例化,但我正在考虑通过接口发送事件(尤其是RoutedEvents)。因此,我的自

我试图在WPF中构建一个应用程序,在这里我想处理连接到一台计算机的多个键盘的输入(按键事件)。因此,我有一个类,在这个类中我重写了WndProc()方法,并且能够从不同的键盘设备接收输入。在执行此操作时,我使用MainWindow句柄注册该类,因此该窗口可以接收CLR键盘事件。但这不是问题

问题是,现在我正在WPF中开发
UserControl
,它也可以响应这些多键盘事件。这些
UserControls
将在同一窗口中实例化,但我正在考虑通过接口发送事件(尤其是
RoutedEvents
)。因此,我的自定义UserControl类只是实现了该接口,我就可以开始了

你们知道怎么做吗,我对WPF很陌生,所以我遇到了一些困难


提前感谢

所以,我想出了办法。我有一个名为
BIFUserControl
的类,它实现了我创建的接口,用于处理连接到同一台计算机的多个键盘上的事件。该接口称为
IMultiKeyboardEvents
。我还有一个只读集合,它将每个键盘设备的当前状态存储为
KeyboardDevice
类的实例

因此,基本上我知道每个键盘设备的输入焦点是什么,它在
BIFKeyboardDevice
类中表示为一个属性。因此,当从Keyboard manager类引发CLR事件时,我实际上可以调用具有特定控件输入焦点的确切类中的接口方法实现

下面是由自定义用户控件类实现的接口
IMultiKeyboardEvents
的代码:

public interface IMultiKeyboardEvents  
{
    event MultiKeyEventHandler MultiKeyDown;
    event MultiKeyEventHandler MultiKeyUp;

    void OnMultiKeyDown(MultiKeyEventArgs);
    void OnMultiKeyDown(MultiKeyEventArgs);
}
在覆盖WndProc()方法的键盘管理器类中,我有一个处理输入事件的方法,如下所示:

void ProcessInput(Message message)
{
    // Code sample which raises just the key down event
    switch (rawInput.keyboard.Message)
    {
        case (uint) BIFWin32.WindowMessage.WM_KEYDOWN:
        {
            if (BIFDeviceCollections.MouseCollection[ID].MouseFocusElement is IMultiKeyboardEvents)
            {
                IMultiKeyboardEvents widget = 
                (IMultiKeyboardEvent)BIFDeviceCollections.MouseCollection[ID].MouseFocusedElement;
                widget.OnMultiKeyDown(eventArgs);
            }
            break;
        }
        case (uint) BIFWin32.WindowMessage.WM_KEYUP:
        {
            if (BIFDeviceCollections.MouseCollection[ID].MouseFocusElement is IMultiKeyboardEvents)
            {
                IMultiKeyboardEvents widget = 
                (IMultiKeyboardEvent)BIFDeviceCollections.MouseCollection[ID].MouseFocusedElement;
                widget.OnMultiKeyUp(eventArgs);
            }
            break;
        }
    }
}

这只是在我的UserControl类中调用OnMultiKeyDown方法的实现,我不必在用户控件类中使用键盘管理器实例并连接事件来侦听它们。此外,由于我已经收集了所有设备对象(鼠标和键盘),它们维护一个字段,说明每个设备的当前焦点元素,并且我已经配对了每个鼠标和键盘设备,因此我可以直接使用此信息来引发事件

为什么要添加额外的接口步骤来“发送”事件。只需像平常一样将侦听器附加到它们。因为在这种情况下,我的UserControl类必须知道KeyboardManager类实例(它实际上引发所有键盘事件),并且此KeyboardManager在主窗口中实例化。您的用户控件必须以某种方式与事件挂钩。此外,根据您的描述,所有内容(用户控件、键盘管理器等)都位于同一窗口中,因此您的控件与管理器位于同一范围内。除非你脑子里有更宏伟的计划,否则就把它连接起来,完成它。是的,我可以做到,因为这个KeyboardManager实例在同一个范围内。但为了保持事情的独立和干净,我决定采用界面方式。无论如何,我已经实现了一个CLR事件,通知我的自定义UserControl类键盘事件,我可以这样做,因为我确切地知道输入焦点是什么(用户控件)对于每个键盘设备,使用这个想法,我实际上可以在我希望调用的确切类中调用接口方法。无论如何,谢谢A.R.的建议。发布一些代码。我想看看所有的东西是如何连接起来的,界面是如何让它更“干净”的嗨,A.R.我已经发布了一些代码。请看一看,我真的希望这是足够的,我也感谢你的建议:-)好的,我知道你在这里做什么。因此接口的实现者(IMultiKeyboard…)实际上并不处理任何事件(因为他们不在侦听),当其他东西处理实际事件时,您只发送一些参数。那么为什么您的接口定义上定义了两个事件呢?这些是否在代码中的其他地方使用?是的,没错……接口的实现者实际上并不处理任何事件。它类似于简单的
System.Windows.Controls.Button
类,该类从WPF框架获取所有输入事件(鼠标、触摸等),但反过来又为程序员提供其他事件,如
单击
。因此,在我的例子中,
BIFUserControl
类实际上是一个基类,我将使用它来开发更具体的多键盘小部件(例如多键盘post)。因此,每当出现输入事件(如按键)时,UserControl类都会执行一些操作并引发一些其他事件