如何保持加载 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()
.
我创建了 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()
.