重现我的情况(.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();
}
}
}
答案 0 :(得分:4)
我使用我的MSDN支持合同来解决这个问题。工程师能够从yunusayd的样本中重新编写并确认它几乎肯定是WindowsFormsHost中的一个错误。
感谢yunus提供最小的repro示例和微软的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;
}
}
}
}
}
}
答案 1 :(得分:0)
我们在其中一个应用程序中遇到了类似问题,发现升级到.net 4.5似乎修复了我们应用程序的WPF / WinForms焦点问题的很大一部分,包括与此类似的问题。
此外,WindowsFormHost的.net 4.5版本中不再存在_focusedChild字段