我有一个WinForms用户控件,其中包含一个WPF自定义列表框。在WinForms用户控件被禁用然后重新启用后,WinForms用户控件中的WPF控件没有响应。还有其他人经历过这个吗?
每次控件被禁用/启用以解决问题时,我们必须破解灵魂去除并重新添加元素主机。
wpfControl.Enabled = false;
...
wpfControl.Enabled = true;
用于在用户控件的WinForms EnabledChanged方法中修复它的Hack
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;
}
似乎存在内存泄漏,处理元素主机仍然存在,直到托管WinForms用户控件的父窗体关闭。
答案 0 :(得分:7)
我的同事(感谢KwB)成功找到了解决此问题的方法:http://support.microsoft.com/kb/955753
它涉及继承ElementHost并手动告诉窗口区域启用:
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);
}
答案 1 :(得分:1)
元素主机是否订阅了WPF用户控件中的事件?如果是这样,并且事件在尝试处理元素主机之前没有取消连接,它将在内存中挂起,直到WPF控件被释放(并且因为它看起来你在整个过程中使用相同的控件实例,这不是直到表格关闭。)