Ghassan Karwchan
Ghassan Karwchan

Reputation: 3539

Setting the focus for a Windows Forms element hosted in WPF

I have a complex WPF Window with a TabControl. One of the TabItems hosts a WindowsFormsHost, which host some old Windows Forms controls.

When I navigate to this tab, I try to set the focus on one of those controls. Keyboard.Focus() doesn't work because it requires an IInputElement, which the old windows forms controls don't support. So, I am calling the Focus() method of the old Windows Forms control themselves, but for some reason it is not working.

I put the code to call the Focus() on every event you can think of:

  1. TabControl's SelectionChanged event
  2. TabItem's IsVisibleChanged event
  3. TabItem's GotFocus event

None of them work. Anybody have any ideas?

Thanks

Upvotes: 2

Views: 2615

Answers (1)

HolaJan
HolaJan

Reputation: 916

My solution:

private void TabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    Dispatcher.BeginInvoke(() =>
        {
            FormsControl.Focus();
            System.Windows.Input.Keyboard.Focus(ControlHost);
            Dispatcher.BeginInvoke(() => FormsControl.Focus());
        });          
}

public static class DispatcherExtensions
{
    /// <summary>
    /// Executes the specified delegate asynchronously on the thread the System.Windows.Threading.Dispatcher is associated with.
    /// </summary>
    /// <param name="dispatcher">System.Windows.Threading.Dispatcher</param>
    /// <param name="a">A delegate to a method that takes no arguments and does not return a value, which is pushed onto the System.Windows.Threading.Dispatcher event queue.</param>
    /// <returns>An object, which is returned immediately after Overload:System.Windows.Threading.Dispatcher.BeginInvoke is called, that represents the operation that has been posted to the System.Windows.Threading.Dispatcher queue.</returns>
    public static DispatcherOperation BeginInvoke(this Dispatcher dispatcher, Action a)
    {
        return dispatcher.BeginInvoke(a, null);
    }
}

Upvotes: 2

Related Questions