KeyDown 事件不会从 UWP 中的选定网格触发

KeyDown event doesn't trigger from selected grid in UWP

我正在开发像日历这样的自定义控件,其中我有一个面板作为月视图,其中网格单元格排列为日期单元格。网格有一个以 TextBlock 作为内容模板的内容呈现器。一切正常。 Pointerpressed、pointerReleased 和 OnTapped 覆盖方法对 Grid 工作正常,但 OnKeyDown 覆盖方法或 KeyDown 事件不会从中触发。我也尝试使用 PreviewKeyDown。请帮我解决这个问题。

KeyDown event doesn't trigger from selected grid in UWP

问题是 Grid 没有获得焦点,所以事件不会按预期触发。更好的方法是监听 CoreWindow KeyDown 事件,因为当应用程序 运行 在前台时,CoreWindow 会自动获得焦点。

Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
   MyBlock.Text = args.VirtualKey.ToString();
}

按键按下事件仅由键盘焦点控制触发。 Grid 不是控件,Grid 是 Panel。在UWP中,只有控件可以设置焦点。

可以写一个空控件,添加到Grid中设置控件焦点。

class Foo : Control
{
    protected override void OnKeyDown(KeyRoutedEventArgs e)
    {
        Debug.WriteLine("Foo key down");
    }
}

    <Grid x:Name="Grid2" Margin="10,10,10,10" Width="100" Background="#565656" HorizontalAlignment="Right" 
          KeyDown="Grid2_OnKeyDown">
        <local:Foo x:Name="Foo"></local:Foo>
    </Grid>

您可以编写任何代码来帮助在按下 Grid2 键时进行调试。

    private void Grid2_OnKeyDown(object sender, KeyRoutedEventArgs e)
    {
        Debug.WriteLine("Grid2 key down");
    }

然后您可以在单击 Grid2 时设置 Foo 属性 焦点。

    private async void Grid2_OnPointerReleased(object sender, PointerRoutedEventArgs e)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Foo.Focus(FocusState.Keyboard); });
    }

尝试 运行 代码,您可以看到输出 windows 当您单击 Grid2 并按下按键时显示消息。

但是为什么我把代码写在dispatcher里,因为我要让Foo控件获得焦点。如果我不使用调度程序,指针焦点将位于 Grid 而不是任何 UIElement 焦点键盘中。