我有一个程序,由许多不同的人在不同的年份编写。有些应用程序是用Winforms编写的,有些应用程序是用WPF编写的。我有一个在某些窗口(WPF)中使用的WPF用户控件,并且我试图将其放置到程序的Winforms窗口之一中。我同时拥有该控件的WPF和WinForms版本,与新的WPF版本相比,WinForms控件非常复杂且存在一些错误,这就是为什么我将其放置在较旧的WinForms窗口中。
此WPF用户控件内部有一个WinForms控件,因为我找不到所需的WPF版本的控件(十六进制框)。在我的winforms表单内部,我放置了一个承载此UserControl(WPF)的ElementHost。直到关闭窗口(直到我收到一个说InvalidWindowHandle的Win32Exception),它都可以正常工作。没有有用的堆栈跟踪。
当我关闭表单时,我将处理explorerWPF(它的元素宿主)。部署解释器WPF时,它将依次部署十六进制框和WinFormHostedControl。
当我关闭PathfindingEditor时,我正在处理很多事情以防止内存泄漏。
(pathfindingeditor.cs)
private void PathfindingEditor_FormClosing(object sender, FormClosingEventArgs e)
{
//Nullify things to prevent memory leaks
interpreterWPF.Dispose();
interpreterWPFElementHost.Child = null;
interpreterWPFElementHost.Dispose();
...
(interpreterwpf.xaml.cs)
public override void Dispose()
{
Interpreter_Hexbox = null;
Interpreter_Hexbox_Host.Child.Dispose();
Interpreter_Hexbox_Host.Dispose();
}
目前还不确定该怎么办。取代winforms控件的新WPF控件要简单得多,而且故障少得多。将旧表单更改为WPF会很棒,但是我没有找到合适的库来执行它需要执行的复杂任务,WPF中Winforms托管的元素有很多缺点,这就是为什么我不会比hexbox更深入
我已经阅读了Dispatcher.InvokeShutdown(),但这似乎完全关闭了WPF UI线程。我怀疑这就是我想要的。
答案 0 :(得分:1)
尝试将ElementHost的WPF根元素的AutomationProperties.NameProperty设置为一些有效的字符串,例如如下:
elementHost.HandleCreated += delegate(object sender, EventArgs e)
{
HwndSource source = (HwndSource)HwndSource.FromVisual(elementHost.Child);
AutomationProperties.SetName(source.RootVisual, "elementHost");
};
在附加Visual Studio调试器时,我收到了以下异常且很短的调用栈的异常:
Source "WindowsBase"
StackTrace "at MS.Win32.UnsafeNativeMethods.GetWindowText(HandleRef hWnd, StringBuilder lpString, Int32 nMaxCount)"
没有调试器,则异常不可见。
在WPF框架方法System.Windows.Automation.Peers.GenericRootAutomationPeer.GetNameCore
中引发异常,因为在该方法中使用ElementHost WPF部分的已放置的窗口句柄base.Hwnd
的方法如下:
namespace System.Windows.Automation.Peers // from PresentationCore.dll
{
public class GenericRootAutomationPeer : UIElementAutomationPeer
{
...
protected override string GetNameCore()
{
string text = base.GetNameCore();
if (text == string.Empty)
{
IntPtr hwnd = base.Hwnd;
if (hwnd != IntPtr.Zero)
{
try
{
StringBuilder stringBuilder = new StringBuilder(512);
Throws ======> MS.Win32.UnsafeNativeMethods.GetWindowText(new HandleRef(null, hwnd), stringBuilder, stringBuilder.Capacity);
text = stringBuilder.ToString();
}
catch (Win32Exception)
{
}
if (text == null)
{
text = string.Empty;
}
}
}
return text;
}
设置AutomationProperties.NameProperty可确保base.GetNameCore()
返回一个有效的字符串,从而导致有问题的代码被跳过。