开发者

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.


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);
} 


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.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜