wpfwpf-controlsfocuskeyboard-eventswpf-4.0

How to make my control focusable?


I have a control

public class FocusTestControl : Control {
    public FocusTestControl() {
        DefaultStyleKey = typeof(FocusTestControl);
    }
}

Here is it's default style

    <Style
    TargetType="local:FocusTestControl">
    <Setter
        Property="Focusable"
        Value="True" />
    <Setter
        Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Border
                        Background="AliceBlue" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I put this control on a window:

<Window
x:Class="MakeWpfControlFocusable.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MakeWpfControlFocusable"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition
            Height="35" />
    </Grid.RowDefinitions>
    <local:FocusTestControl />
    <StackPanel
        Grid.Row="1"
        Orientation="Horizontal">
        <TextBlock
            Text="Focused element: " />
        <TextBlock
            Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=KeyboardFocusedElement}" />
        <TextBox
            Text="Text" />
    </StackPanel>
</Grid>

But clicking on control doesn't make it focused (I mean KebordFocus)

Actually, my task is handle the KeyDown and KeyUp events. But it is impossible when element has no keybord focus.


Solution

  • Keybord focus can be set by pessing Tab keyboard key. But it is not set when clicking on the Control. I've subscribed to the MouseDown event and set focus manually in the handler.

    public class FocusTestControl : Control, IInputElement {
    
        public FocusTestControl() {
            DefaultStyleKey = typeof(FocusTestControl);
            MouseDown += FocusTestControl_MouseDown;
        }
    
        void FocusTestControl_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Keyboard.Focus(this);
        }
    }