Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF WinForms Interop issue with Enable / Disable

I have a WinForms usercontrol hosting a WPF custom Listbox in it. After the WinForms user control gets disabled and then re-enabled the WPF control in the WinForms usercontrol is unresponsive. Has anyone else experienced this?

We had to hack a soultion into remove and re-add the element host each time the control gets disable / enabled to fix the issue.

WinForms

wpfControl.Enabled = false;
...
wpfControl.Enabled = true;

Hack for fixing it in the WinForms EnabledChanged method for the usercontrol

if ( Enabled ) 
{
  ElementHost oldEh = ctlElementHost;
  ElementHost eh = new ElementHost();
  eh.Name = oldEh.Name;
  oldEh.Child = null;
  eh.Child = wpfControl;
  this.Controls.Remove( ctlElementHost );
  this.Controls.Add( eh );
  eh.Dock = DockStyle.Fill;

  oldEh.Dispose();
  ctlElementHost = eh;
}

There seems to be a memory leak where the disposed element hosts are still sticking around until the parent form that was hosting the WinForms usercontrol gets closed.

like image 571
Mark Boltuc Avatar asked Mar 17 '09 18:03

Mark Boltuc


2 Answers

A co-worker (thanks KwB) of mine managed to find a fix for this issue: http://support.microsoft.com/kb/955753

It involves inheriting from ElementHost and manually telling the window region to enable:

public class MyElementHost : ElementHost
{
    protected override void OnEnabledChanged(EventArgs e)
    {
        SynchChildEnableState(); 

        base.OnEnabledChanged(e);
    } 

    private void SynchChildEnableState()
    {
        IntPtr childHandle = GetWindow(Handle, GW_CHILD);
        if (childHandle != IntPtr.Zero)
        {
            EnableWindow(childHandle, Enabled);
        }
    } 

    private const uint GW_CHILD = 5; 

    [DllImport("user32.dll")]
    private extern static IntPtr GetWindow(IntPtr hWnd, uint uCmd); 

    [DllImport("user32.dll")]
    private extern static bool EnableWindow(IntPtr hWnd, bool bEnable);
} 
like image 56
Mark Boltuc Avatar answered Nov 20 '22 11:11

Mark Boltuc


Does the element host subscribe to events from the WPF user control? If so, and the events aren't unwired before trying to dispose the element host, it will hang around in memory until the WPF control is disposed (and since it looks like you're using the same instance of the control throughout, that isn't until the form is closed.)

like image 1
Lee Roth Avatar answered Nov 20 '22 13:11

Lee Roth