Commandbar 没有获得焦点——必须使用键盘

Commandbar not getting focus -- gotta use keyboard

我的小项目进展顺利,但是我遇到了一些可能很愚蠢的事情...

不知何故,当我打开应用程序时,没有任何东西获得焦点,我必须使用 "tab" 键才能将焦点移动到命令栏并能够使用键盘快捷键。

然后....

当我使用 Scrollviewer 移动图像或缩放时,我无法再次使用键盘快捷键,直到我使用 "tab" 将其移动到命令栏。

我试过了

cmdbar.Focus(FocusState.Programmatic);

在应用程序中我认为它可能有用的地方都有一点,但无济于事。我也试过使用键盘加速器,但没有用。有什么建议吗?

这是我的 XAML 代码:

<Page.Resources>
    <DataTemplate x:Key="myResourceTemplate">
        <TextBlock Text="{Binding}" MaxHeight="10" FontSize="8" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" LineHeight="9" Height="Auto" />

    </DataTemplate>
</Page.Resources>

<Page.BottomAppBar>
    <CommandBar x:Name="cmdbar"  ClosedDisplayMode="Compact" HorizontalAlignment="Left" HorizontalContentAlignment="Left" VerticalAlignment="Center" KeyUp="kb_openkey" Opacity="1" Visibility="Visible" Background="#260000FF">
        <CommandBar.Content>
            <Grid/>
        </CommandBar.Content>
        <AppBarButton Icon="ZoomIn" Label="AppBarButton" Tapped="Zoomin_Click"/>
        <AppBarButton Icon="ZoomOut" Label="AppBarButton" Tapped="Zoomout_Click"/>

        <AppBarToggleButton x:Name="randomstatus" Icon="Shuffle" Label="Random" Tapped="Togglerandom"/>

        <... a bunch of other buttons >

    </CommandBar>
</Page.BottomAppBar>

<Grid x:Name="imggrid" Background="Black" BorderBrush="Black" KeyUp="kb_openkey">
    <ScrollViewer x:Name="imageView_scroller" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" ZoomMode="Enabled" RequestedTheme="Dark" KeyUp="kb_openkey">
        <Image x:Name = "ctlImage" Grid.Column ="0" VerticalAlignment = "Stretch"  HorizontalAlignment = "Stretch"  Stretch = "Uniform"
            PointerWheelChanged="ctlImage_PointerWheelChanged"
            ManipulationMode = "TranslateX, TranslateY, Scale" 
            ManipulationStarted = "ctlImage_ManipulationStarted" 
            ManipulationDelta = "ctlImage_ManipulationDelta"
            ManipulationCompleted = "ctlImage_ManipulationCompleted"   

            KeyUp="kb_openkey"
           >
            <Image.RenderTransform>
                <CompositeTransform x:Name="image_Transform" ></CompositeTransform >
            </Image.RenderTransform >
        </Image>
    </ScrollViewer>

</Grid>

这是我处理键盘输入的方式:

    void kb_openkey(object sender, KeyRoutedEventArgs e)
    {
        if ((int)e.Key >= 1 && (int)e.Key <= 255)
        {
            switch ((int)e.Key)
            {
                case 70: //A
                    ....dothis....;
                    break;
                case 65: //A
                    .... dothat....;
                    break;
             }
        }
    }

you do not need to set focus in order to use KeyboardAccelrators as shortcuts. Hence you do not need the keyup or keydown events on your image or command bar, unless they have some other task irrelevant of setting focus.

您应该在命令栏中使用 KeyBoardAccelratorsAccessKey 以及任何选项修饰符,例如 CtrlShift

AppBarButton

上的 AccessKey 示例
<AppBarButton 
    Icon="Copy" 
    Label="Copy" 
    ToolTipService.ToolTip="Copy (Ctrl+C)" 
    Click="OnCopy" 
    AccessKey="C">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="Control" 
        Key="C" />
    </AppBarButton.KeyboardAccelerators>
</AppBarButton>

you can find more details in the link of docs I provided above.

更新

当您点击另一个 UI 元素时,前一个元素的焦点会自动移除,您不需要在图像和命令栏上使用 KeyUp 事件,你只需要使用全局 CoreWindow.KeyDown 就可以帮助你完成你想要完成的任何关键相关命令

@touseefbsb,很有用!!!谢谢!无论什么获得焦点和被点击,它都会处理键。

所以我的代码是,供参考:

在XAML的页面部分,添加:

Loaded="initkbd"
Unloaded="unloadkbd"

并在 C# 部分添加:

    //Add the key handler method to the KeyDown handlers
    private void initkbd(object sender, RoutedEventArgs e)
    {
        Window.Current.CoreWindow.KeyDown += kb_openkey;
        cmdbar.Content = "Added to keys";
    }

    //Remove the keyhandler method from the list
    private void unloadkbd(object sender, RoutedEventArgs e)
    {
        Window.Current.CoreWindow.KeyDown -=kb_openkey;
    }

然后,密钥处理程序如下所示:

    private void kb_openkey(CoreWindow sender, KeyEventArgs e)
    {
        //Mark the event as handled
        e.Handled = true;


        int keypressed = (int) e.VirtualKey;

        //Than handle the key, based on its keycode
        if ((int)keypressed >= 1 && (int)keypressed <= 255)
        {                
            switch (keypressed)
            {
                case 70: //F
                    //do something when F is presed
                    break;

                case 76:  //L dialog to show items
                    //Do something when L is pressed
                    break;

            }
        }

     }