locked
Capture KeyDown in control RRS feed

  • Question

  • Hi,

    I create a custom class in a windows store app. The class derived from Control. If I override OnKeyDown in does not work correctly for me. For example:

    I move to my Control with tab / shift+tab. The OnGotFocus-Method is called and OnKeyDown work. But if I click on the control with the Mouse the methods don’t get called.

    protected override void OnKeyDown(KeyRoutedEventArgs e){
    //not called after PointerPressed
    }
    
    protected override void OnGotFocus(RoutedEventArgs e){
    //called by tab-navigation and PointerPressed
    }
    In the template I have 2 UserControl's that contains shapes and a thumb. What I do wrong?

    Wednesday, January 1, 2014 4:36 PM

Answers

  • Hi Joye,

    Thanks for your code, and I can reproduce the issue, the control cannot be focused by mouse click.

    I would not suggest you to use OnPointerPressed event, which can be only fired with PointPressed, only a few milliseconds, you can use Tapped instead:

            protected override void OnTapped(TappedRoutedEventArgs e)
            {
                this.Focus(Windows.UI.Xaml.FocusState.Pointer);
            }
    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Joye Beginner Friday, January 3, 2014 1:05 AM
    Thursday, January 2, 2014 8:07 AM
    Moderator

All replies

  • Hi Joye,

    Could you share a sample code with us for a better analysis?

    I'm not quite sure why you meet such issue, but KeyDown is a routed event, perhaps the event is handled by other stuff, maybe another UserControl? Hardly to tell the reason.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, January 2, 2014 1:56 AM
    Moderator
  • Thanks for the answer. Here is a short example:

     [TemplatePart(Name = "PART_Border", Type = typeof(Border))]
        public sealed class CustomControl1 : Control
        {
            public CustomControl1()
            {
                this.DefaultStyleKey = typeof(CustomControl1);
            }
    
            protected override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
                border = (Border)this.GetTemplateChild("PART_Border");
            }
    
            Border border = null;
    
            protected override void OnKeyDown(KeyRoutedEventArgs e)
            {
                base.OnKeyDown(e);
    
                if (border != null)
                    switch (e.Key)
                    {
                        case Windows.System.VirtualKey.Left:
                            border.Margin = new Thickness(border.Margin.Left - 1, border.Margin.Top, 0, 0);
                            break;
                        case Windows.System.VirtualKey.Right:
                            border.Margin = new Thickness(border.Margin.Left + 1, border.Margin.Top, 0, 0);
                            break;
                    }
            }
    
            protected override void OnGotFocus(RoutedEventArgs e)
            {
                base.OnGotFocus(e);//Not called by PointerPressed
                if (border != null)
                    border.Background = new SolidColorBrush(Color.FromArgb(255, 0xFF, 0, 0));
            }
    
            protected override void OnLostFocus(RoutedEventArgs e)
            {
                base.OnLostFocus(e);
                if (border != null)
                    border.Background = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0xFF));
            }
        }

    the template:

        <Style TargetType="local:CustomControl1">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:CustomControl1">
                        <Border
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                            <Border HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" Width="50" Background="DarkBlue" Name="PART_Border"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    and the MainWindow.xaml:

    <Page
        x:Class="App15.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App15"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Button Content="other control 1" HorizontalAlignment="Left" Margin="180,10,0,0" VerticalAlignment="Top" Height="113" Width="358"/>
            <local:CustomControl1 HorizontalAlignment="Left" Background="Wheat" Margin="342,206,0,0" VerticalAlignment="Top" Height="305" Width="550"/>
            <Button Content="other control 2" HorizontalAlignment="Left" Margin="731,543,0,0" VerticalAlignment="Top" Height="113" Width="358"/>
    
        </Grid>
    </Page>
    

    These are my Steps:

    1. Click on button 1
    2. press tab > border goes red
    3. press left/right > border move
    4. press tab > border goes blue

    All OK, but...

    1. Click on custom control > border do not change the color
    2. press left/right > border not mode

    I tried also to set the Keyboard Focus by PointerPressed:

            protected override void OnPointerPressed(PointerRoutedEventArgs e)
            {
                base.OnPointerPressed(e);
                this.Focus(Windows.UI.Xaml.FocusState.Keyboard);
            }
    But the control lost the focus directly after PointerReleased get called. If I hold the mouse button, I can use the keyboard.
    Thursday, January 2, 2014 2:52 AM
  • Hi Joye,

    Thanks for your code, and I can reproduce the issue, the control cannot be focused by mouse click.

    I would not suggest you to use OnPointerPressed event, which can be only fired with PointPressed, only a few milliseconds, you can use Tapped instead:

            protected override void OnTapped(TappedRoutedEventArgs e)
            {
                this.Focus(Windows.UI.Xaml.FocusState.Pointer);
            }
    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Joye Beginner Friday, January 3, 2014 1:05 AM
    Thursday, January 2, 2014 8:07 AM
    Moderator
  • Thanks a lot! It works perfect =)
    Friday, January 3, 2014 1:06 AM