Search code examples
c#.netwpfwinformsvisual-studio-2010

Winforms window loses focus when called from WPF


I have a WPF .Net Framework application, which calls a Winforms window (DLL). When this new Winforms window is shown, it is then sent to the back of the WPF application. As if the new window loses focus as soon as it opens. Or the WFP window is always keeping focus

The Winforms window call in the button click event in WPF

graficha.abre(2); 

Winforms window opening code, In this case, call the Show method

public void abre(int modoShow = 1)
        {
            Form1 Form_1 = new Form1(Empresa,EmpIni,EmpFim,DataIni,DataFim);

            ...

            if (modoShow == 1)
                Form_1.ShowDialog();
            else
                Form_1.Show();

            
        }

Solution

  • I'm not sure where the issue generates from, it shouldn't happen, unless some other code causes the activation of the WPF Window (or, well, you simply double-click an UI element to execute that code).

    Anyway, you could set the Owner of the WinForm's Form to the Handle of the WPF Windows, so the Form is going to always be on top of that Window.
    You can use an intermediate NativeWindow to expose the required IWin32Window interface

    var owner = new NativeWindow();
    owner.AssignHandle((PresentationSource.FromVisual(this) as HwndSource).Handle); 
    Form_1.Show(owner);
    

    Caveat: you should release the Handle of the NativeWindow when not needed anymore.
    Also, if you need to present more than one Form, you could probably initialize and store the NativeWidow as a Field, reuse it when needed, then release the handle when the Window itself closes:

    NativeWindow owner = new NativeWindow();
    
    protected override void OnSourceInitialized(EventArgs e)
    {
        var handle = HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()).Handle;
        owner.AssignHandle(handle);
    
        base.OnSourceInitialized(e);
    }
    
    protected override void OnClosed(EventArgs e) {
        owner.ReleaseHandle();
        base.OnClosed(e);
    }
    

    Then assign the NativeWindow as the Owner of a Form when needed:

    SomeForm.Show(owner);
    // OR
    SomeOtherForm.ShowDialog(owner);