[英]WindowsFormsHost steals focus on activating application even activating by application's other wpf form
重現我的案子(.net 4.0)
您的項目已准備就緒,
而且您會看到您無法將焦點設置在Window1中的文本框上,因為MainWindow Texbox(在winformshost中將使您的焦點轉移到已激活的應用程序上)
任何想法?
MainWindow.xaml
<Window x:Class="WinFormsHostFocusProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WinFormsHostFocusProblem"
xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
Title="MainWindow" Height="350" Width="525">
<Grid>
<my:WindowsFormsHost Focusable="False" >
<local:UserControl1>
</local:UserControl1>
</my:WindowsFormsHost>
</Grid>
</Window>
MainWindow.xaml.cs
namespace WinFormsHostFocusProblem
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Window1 window1 = new Window1();
window1.Show();
}
}
}
Window1.xaml
<Window x:Class="WinFormsHostFocusProblem.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WinFormsHostFocusProblem"
xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
Topmost="True"
Title="Window1" Height="300" Width="300" Background="Red">
<Grid>
<TextBox Height="25">asd</TextBox>
</Grid>
</Window>
Window1.xaml.cs
namespace WinFormsHostFocusProblem
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
我使用了MSDN支持合同來獲取此問題的答案。 工程師能夠從yunusayd的示例進行復制,並確認幾乎可以肯定這是WindowsFormsHost中的錯誤。
感謝yunus提供了最少的repro示例,並感謝Microsoft的Keith解決了該問題並在不到一天的時間內提供了解決方法。
解決方法代碼如下。 它通過使用.NET反射來更改WindowsFormsHost中使用的私有變量並禁用該錯誤的觸發器,從而起作用。 根據我與之合作的工程師的說法,這依賴於WPF內部,但是他與產品團隊成員進行了交談,並且應該安全使用。 當然,不能保證沒有副作用,但是到目前為止,在多個WPF窗口中使用多個WindowsFormsHosts進行測試時,我還沒有發現任何問題(嵌套可能會更棘手)。 我修改了原始的解決方法,以與多個窗口通用。 您可以輕松地在Application_Deactivated事件中對特定窗口和命名的WindowsFormsHost控件進行硬編碼引用,並跳過整個“ 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;
}
}
}
}
}
}
我們在一個應用程序中遇到了類似的問題,發現升級到.net 4.5似乎已解決了我們應用程序的WPF / WinForms焦點問題的很大一部分,包括與此類似的問題。
此外,_netedChild字段在WindowsFormsHost的.net 4.5版本中不再存在
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.