UWP中的自定义应用内键盘

3

我想在UWP中创建自定义的屏幕键盘。它需要成为应用程序的一部分,因为它将用于大型桌面或白板设备,因此对键盘位置的完全控制非常重要(在桌子上旋转)。

在WPF中,我已经通过创建具有Target属性的键盘控件来制作了这样的自定义键盘。当按下键时,它会使用UIElement.RaiseEvent(...)在目标上引发KeyEvent或TextComposition事件。 但是在UWP中,没有RaiseEvent函数,似乎也没有办法为开发人员引发路由事件。

我想使用本机文本事件(KeyDown事件、TextComposition事件等),因此手动编辑TextBox的Text属性的解决方案(像这样的)是不可接受的。

这个页面解释了如何创建一个监听Text Services Framework的控件。我认为一个解决方案是创建一个自定义的文本服务,但我没有找到任何相关的文档。


你有没有找到解决方案? - Dan Is Fiddling By Firelight
@DanNeely 不好意思,目前没有。我们现在没有在开发UWP。 - Gael
1个回答

2
您可以使用Windows.UI.Input.Preview.Injection命名空间中的类和受限制的inputInjectionBrokered功能来完成您正在寻找的部分内容。这适用于KeyUpKeyDownPreviewKeyUpPreviewKeyDown事件,只要您不需要将按键发送到应用程序之外的任何地方。
对于非拉丁脚本,它超出了我所处理的范围,因此我不知道是否可以扩展到生成TextComposition事件的输入法编辑器。
Martin Zikmund在这里演示了如何实现,同时在github上提供了示例解决方案。
关键点是您需要编辑您的Package.appxmanifest文件(而不是通过设计器)以包括:
<Package>
    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    IgnorableNamespaces="rescap"
</Package>

并且

<Capabilities>
    <rescap:Capability Name="inputInjectionBrokered" />
<Capabilities>

你可以通过以下方式模拟输入并触发本地键盘事件:

private async void TypeText()
{
    Input.Focus(FocusState.Programmatic);
    //we must yield the UI thread so that focus can be acquired
    await Task.Delay(100); 

    InputInjector inputInjector = InputInjector.TryCreate();
    foreach (var letter in "hello")
    {
        var info = new InjectedInputKeyboardInfo();
        info.VirtualKey = (ushort)((VirtualKey)Enum.Parse(typeof(VirtualKey), 
                                   letter.ToString(), true));
        inputInjector.InjectKeyboardInput(new[] { info });

        //and generate the key up event next, doing it this way avoids
        //the need for a delay like in Martin's sample code.
        info.KeyOptions = InjectedInputKeyOptions.KeyUp;
        inputInjector.InjectKeyboardInput(new[] { info });
    }
}

谢谢!终于有答案了。我稍后会测试一下。 - Gael
@Gael 如果你在测试中发现任何有趣的事情,请在这里跟进。 当应用程序达到那个点时,我还没有超越这个原型来证明我能否制作自定义键盘。 在那之前,我有很多其他需要完成的事情。 - Dan Is Fiddling By Firelight
1
您可以轻松地将此扩展到非拉丁脚本:https://stackoverflow.com/a/59755604/130060 - Emiswelt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接