Командная панель не получает фокус, нужно использовать клавиатуру

Мой маленький проект продвигается хорошо, однако я спотыкаюсь о что-то, что, вероятно, глупо...

Каким-то образом, когда я открываю приложение, ничего не фокусируется, мне приходится использовать клавишу «вкладка», чтобы переместить фокус на панель команд и использовать сочетания клавиш.

А потом....

КОГДА я использую Scrollviewer для перемещения изображения или масштабирования, я не могу снова использовать сочетания клавиш, пока не использую «вкладку», чтобы переместить его на панель команд.

я пытался

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;
             }
        }
    }

person Francois Gagnon    schedule 14.09.2018    source источник
comment
используйте keydown вместо keyup для более быстрого ответа, bcz key down вызывается при нажатии клавиши, а key up не вызывается до тех пор, пока клавиша не будет отпущена.   -  person Muhammad Touseef    schedule 14.09.2018
comment
также что вы подразумеваете под //сделать это и//сделать то? не могли бы вы уточнить, что делается в событии keyup?   -  person Muhammad Touseef    schedule 14.09.2018
comment
//сделать это и //сделать то — это действия, запускаемые клавишами... Я не включил их для простоты......   -  person Francois Gagnon    schedule 14.09.2018


Ответы (2)


вам не нужно устанавливать фокус, чтобы использовать KeyboardAccelrators в качестве ярлыков. Следовательно, вам не нужны события keyup или keydown на вашем изображении или панели команд, если у них нет другой задачи, не связанной с установкой фокуса.

вы должны использовать KeyBoardAccelrators на панели команд. с AccessKey и любыми модификаторами параметров, такими как Ctrl или Shift

пример AccessKey на AppBarButton

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

вы можете найти более подробную информацию по ссылке на документы, которые я предоставил выше.

Обновление :

когда вы нажимаете на другой элемент пользовательского интерфейса, фокус с предыдущего элемента автоматически удаляется, вам не нужно событие KeyUp на вашем изображении, а также на панели команд, вы просто используете глобальный CoreWindow.KeyDown, который может помочь вам в любых ключевых командах, которые вы хотите выполнить

person Muhammad Touseef    schedule 14.09.2018
comment
Хорошо я понял! Но все же мой вопрос заключается в том, как вернуть фокус на панель команд из программы С# после того, как я использовал прокрутку с помощью мыши. Есть и другие функции, которые я хочу привязать к нажатиям клавиш, не являющимся кнопкой на панели команд. Да, я знаю, что вы можете критиковать мой дизайн, но это то, что я хочу сделать, и я хотел бы знать, почему моя клавиатура теряет свои возможности после того, как я использую средство просмотра прокрутки, если я не нажимаю клавишу табуляции, что, очевидно, является вопросом фокуса. . - person Francois Gagnon; 15.09.2018
comment
тогда вы можете просто использовать cmdbar.Focus(FocusState.Programmatic); если вы не хотите использовать вкладку - person Muhammad Touseef; 15.09.2018
comment
см. обновленную часть ответа, возможно, это поможет вам. @ФрансуаГаньон - person Muhammad Touseef; 15.09.2018

@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;

            }
        }

     }
person Francois Gagnon    schedule 15.09.2018