Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
启用/禁用WPF WinForms互操作问题_Wpf_Winforms_Interop - Fatal编程技术网

启用/禁用WPF WinForms互操作问题

启用/禁用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

我有一个WinForms usercontrol,其中托管一个WPF自定义列表框。禁用WinForms用户控件并重新启用后,WinForms用户控件中的WPF控件将无响应。还有其他人经历过吗

每次禁用/启用控件时,我们都必须在remove中插入一个soultion,并重新添加元素主机,以修复该问题

桌面应用程序 用于在usercontrol的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 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);
}