Joseph Sturtevant
Joseph Sturtevant

Reputation: 13360

WPF Maintain Keyboard Focus

I'm creating a UserControl consisting of a TextBox and a ListView. I want keyboard focus to remain with the TextBox as long as the control has keyboard focus (selection changes in the ListView shouldn't remove keyboard focus from the TextBox).

I've tried catching GotKeyboardFocus in the ListView and passing keyboard focus back to the TextBox using Keyboard.Focus(), but this seems to cancel any selection operation in the ListView. The below code shows the problem. Does anyone know how to achieve this functionality?

<Window x:Class="WpfApplication5.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TextBox x:Name="TextBox1" />
        <ListView x:Name="ListBox1" Keyboard.GotKeyboardFocus="ListBox1_GotKeyboardFocus">
            <ListViewItem Content="Able" />
            <ListViewItem Content="Baker" />
            <ListViewItem Content="Charlie" />
        </ListView>
    </StackPanel>
</Window>

using System.Windows;
using System.Windows.Input;

namespace WpfApplication5
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void ListBox1_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            Keyboard.Focus(TextBox1);
        }
    }
}

Upvotes: 4

Views: 11699

Answers (6)

IceX
IceX

Reputation: 21

If you are calling your WPF window from a WinForm you must use this:

System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(wpfWindow);
wpfWindow.show();

from the MSDN documentation.

Thats how I solved my keyboard problem.

IceX

Upvotes: 2

mike a
mike a

Reputation: 1

Ok, this was driving me crazy. Even though set focus to UserControl every time lost focus, still couldn't get my command hot keys to work. All I had to do was to set the property Focusable to true, and voilà, it's working!

Upvotes: 0

JohnWinn
JohnWinn

Reputation:

Put Focusable=false on your ListView.

Upvotes: 0

Bubblewrap
Bubblewrap

Reputation: 7516

It looks like it's possible to change focus in the MouseUp event. I think if you do it too early, like in the GotKeyboardFocus event, you'll steal focus before the listview can handle the event and select the chosen item.

<StackPanel>
    <TextBox x:Name="TextBox1" />
    <ListView x:Name="ListBox1" MouseUp="ListBox1_MouseUp">
        <ListViewItem Content="Able" />
        <ListViewItem Content="Baker" />
        <ListViewItem Content="Charlie" />
    </ListView>
</StackPanel>

private void ListBox1_MouseUp(object sender, MouseButtonEventArgs e)
{
    TextBox1.Focus();
}

Upvotes: 2

Adrian
Adrian

Reputation: 1358

Instead, have you considered just capturing keystrokes and putting those keystrokes into your TextBox?

<Window PreviewKeyDown="Window_PreviewKeyDown" >
    <Grid>
        <TextBox x:Name="TextBox1" />
        <ListBox />
    </Grid>
</Window>

Then in your window's code-behind:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
   TextBox1.Text += e.Key.ToString();
}

You'll have to do extra work for anything like special characters (backspace, etc), and obviously a Key handler for your "Enter" or "Post" operation, but it gives you the ability to just free-form type while the Window has focus and to properly handle the keystrokes as necessary.

Upvotes: 3

Szymon Rozga
Szymon Rozga

Reputation: 18168

This is a hack, but what if instead of listening to the GotKeyboardFocus event, you listen to the SelectionChanged event on the ListBox?

Upvotes: 0

Related Questions