0
votes

I have hosted my custom winform control to the WPF project. I have handled the KeyDown event of my custom control to navigate to the next control when the Tab or Shift+Tab key is pressed.

Here is my code for handling the Tab key,

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    if (e.Handled)
        return;

    if (this.AllowStandardTab)
    {
        Form form = this.FindForm();
        if (form != null)
        {
            if (e.KeyData == (Keys.Tab | Keys.Shift))
            {
                form.SelectNextControl(this, false, true, false, true);
                return;
            }
            else if (e.KeyData == Keys.Tab)
            {
                form.SelectNextControl(this, true, true, false, true);
                return;
            }
        }
    }
}

Its working properly in winforms and navigate to the next control. But its not working in the hosted wpf project.

How can I detect wheter the control is hosted in wpf and moves the focus to the next wpf window while pressing the Tab key?

1
Perhaps your control overrides IsInputKey and always returns true for Keys.Tab? Maybe you should return true/false there based on your AllowStandardTab state so the default handling will happen. I suspect that WFH correctly handles ProcessDialogKey whereas your implementation is specific to WF. When your control is hosted in a WPF window then form above would be null.AndrewS

1 Answers

0
votes

It's working in WPF by default as well by using TAB key. It doesn't matter if the control is from winforms or WPF really. Here's quick example that I've made for you.

<Window x:Class="StackPoC.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:StackPoC"
    mc:Ignorable="d"
    Loaded="Window_Loaded"
    Title="MainWindow" Height="450" Width="800">
<StackPanel>
    <TextBox Text="test x" />
    <TextBox Text="test y" />
    <TextBox Text="test z" />
    <TextBox Text="test w" />
    <Grid Name="containerForWinFormsControl" />
</StackPanel>

Code-Behind:

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Create the interop host control.
        System.Windows.Forms.Integration.WindowsFormsHost host =
            new System.Windows.Forms.Integration.WindowsFormsHost();

        // Create the MaskedTextBox control.
        MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");

        // Assign the MaskedTextBox control as the host control's child.
        host.Child = mtbDate;

        // Add the interop host control to the Grid
        // control's collection of child controls.
        this.containerForWinFormsControl.Children.Add(host);
    }

If I'm thinkin about the reason why it's not working on your site a few things come to my mind. TAB keydown event must be handled somewhere before getting into your winforms control. I don't know either if control's focusable but anyway do you really need to handle this manually? framework do care for us with such things.