启用/禁用WPF WinForms互操作问题
我有一个WinForms usercontrol,其中托管一个WPF自定义列表框。禁用WinForms用户控件并重新启用后,WinForms用户控件中的WPF控件将无响应。还有其他人经历过吗 每次禁用/启用控件时,我们都必须在remove中插入一个soultion,并重新添加元素主机,以修复该问题 桌面应用程序 用于在usercontrol的WinForms EnabledChanged方法中修复它的Hack启用/禁用WPF WinForms互操作问题,wpf,winforms,interop,Wpf,Winforms,Interop,我有一个WinForms usercontrol,其中托管一个WPF自定义列表框。禁用WinForms用户控件并重新启用后,WinForms用户控件中的WPF控件将无响应。还有其他人经历过吗 每次禁用/启用控件时,我们都必须在remove中插入一个soultion,并重新添加元素主机,以修复该问题 桌面应用程序 用于在usercontrol的WinForms EnabledChanged方法中修复它的Hack if ( Enabled ) { ElementHost oldEh = ctl
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 usercontrol的父窗体关闭之前,似乎存在内存泄漏,其中已处置的元素主机仍在继续运行。元素主机是否从WPF用户控件订阅事件?如果是这样,并且事件在尝试处理元素主机之前没有被取消激活,那么它将在内存中挂起,直到WPF控件被处理,并且因为它看起来像是您在整个过程中都在使用同一个控件实例,所以直到表单关闭为止。感谢我的一位同事KwB设法找到了解决此问题的方法: 它涉及从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);
}
不,在元素宿主上没有任何我正在连接的事件。我知道,我需要从内存配置文件中取消这些链接,看起来.NET正在连接正在取消链接的事件。
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);
}