Я использовал свой контракт на поддержку MSDN, чтобы получить ответ на эту проблему. Инженер смог воспроизвести образец юнусайда и подтвердил, что это почти наверняка ошибка в WindowsFormsHost.
Спасибо Юнусу за минимальный пример воспроизведения и Китаю из Microsoft за решение этой проблемы и решение этой проблемы менее чем за один день.
Код обходного пути следует. Он работает с использованием отражения .NET для изменения закрытой переменной, используемой в WindowsFormsHost, и отключения триггера для ошибки. По словам инженера, с которым я работал, это зависит от внутренних компонентов WPF, но он поговорил с членами команды разработчиков продукта, и его следует использовать безопасно. Конечно, нет никаких гарантий отсутствия побочных эффектов, но до сих пор я не обнаружил никаких проблем при тестировании с несколькими WindowsFormsHosts в нескольких окнах WPF (возможно, вложение было бы сложнее). Я изменил оригинальный обходной путь, чтобы работать в общем случае с несколькими окнами. Вы можете также легко жестко кодировать ссылки на определенные окна и именованные элементы управления WindowsFormsHost в событии Application_Deactivation и пропускать всю схему LastActive и методы расширения.
// App.xaml.cs: you must hook up to Application.Deactivated
void Application_Deactivated(object sender, EventArgs e)
{
foreach (Window w in windows)
{
foreach (var host in UI.DependencyObjectExtension.AllLogicalChildren(w).
Where(c => c is WindowsFormsHost))
{
FIELD_FOCUSED_CHILD.SetValue(host, null);
}
}
}
public readonly static FieldInfo FIELD_FOCUSED_CHILD = typeof(System.Windows.Forms.Integration.WindowsFormsHost).
GetField("_focusedChild", BindingFlags.NonPublic | BindingFlags.Instance);
public static class DependencyObjectExtension
{
/// <summary>
/// Returns a collection of o's logical children, recursively.
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public static IEnumerable<DependencyObject> AllLogicalChildren(this DependencyObject o)
{
foreach (var child in LogicalTreeHelper.GetChildren(o))
{
if (child is DependencyObject)
{
yield return (DependencyObject)child;
if (child is DependencyObject)
{
foreach (var innerChild in AllLogicalChildren((DependencyObject)child))
{
yield return innerChild;
}
}
}
}
}
}