如何保持加载 WPF UserControl 并使用 HwndSource(异常问题:Visual Target 的根 Visual 不能有父项)

how to keep WPF UserControl loaded and use HwndSource (problem with Exception : The root Visual of Visual Target cannot have a parent)

我创建了 UserControl 并在外部显示它 window。这意味着我创建了插件,它用于主机应用程序(不是我创建的),它将 WPF UserControl 显示为 GUI。

一切正常,我可以重新打开window并且正常,除了

问题

当 window 由主机应用程序重新创建时。这意味着,当双击 window 时,宿主应用程序更改 window 快速重新创建)并添加自己的window 内的(主机应用程序)面板。然后 我得到这个异常:

System.ArgumentException: The root Visual of Visual Target cannot have a parent

...

at mf_GetViewIP(IntPtr& view) in App.Xaml.csline 78

这是我如何显示 WPF USerControl 的代码

private void mf_GetViewIP(ref IntPtr view)
        {
            try
            {
                if (m_main_view == null) 
                {         
                    m_main_view = new Views.uc_main_view();
                    m_main_view.VerticalAlignment = VerticalAlignment.Stretch;
                    m_main_view.HorizontalAlignment = HorizontalAlignment.Stretch;
                }

                sourceParam = new HwndSourceParameters("Arpegissimo ML");
                sourceParam.PositionX = 0;
                sourceParam.PositionY = 0;
                sourceParam.ParentWindow = view;
                sourceParam.WindowStyle = WS_VISIBLE | WS_CHILD;
                
                source = new HwndSource(sourceParam);
                source.RootVisual = m_main_view; // csline 78 (exception)

            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            if (mfp_wai_set != null)
            {
                mfp_wai_set();
            }
        }

if (m_main_view == null)删除并且m_main_view总是new时,异常消失 这就是我想避免的。


问题

如何保持 m_main_view(不是每次都使用 new)而不得到这个异常?可能吗?我只想避免在第二次显示 GUI 时加载和准备我的视图。

我找到了解决方案

    private void mf_GetViewIP(ref IntPtr view)
    {
        try
        {
            if (m_main_view == null) 
            {         
                m_main_view = new Views.uc_main_view();
                m_main_view.VerticalAlignment = VerticalAlignment.Stretch;
                m_main_view.HorizontalAlignment = HorizontalAlignment.Stretch;
            }

            if (source != null)
            {
                source.Dispose(); // need to clear hold old reference to m_main_view
            }

            sourceParam = new HwndSourceParameters("Arpegissimo ML");
            sourceParam.PositionX = 0;
            sourceParam.PositionY = 0;
            sourceParam.ParentWindow = view;
            sourceParam.WindowStyle = WS_VISIBLE | WS_CHILD;

            source = new HwndSource(sourceParam);
            source.RootVisual = m_main_view;

        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
        if (mfp_wai_set != null)
        {
            mfp_wai_set();
        }
    }

我认为当主机应用程序重新创建 window 时,它发生得如此之快,(从 WPF 端)从 HwndSource 中删除它并不是那么快(因为 windows 是手动重新打开它无一例外),因此需要调用 HwndSource.Dispose().