我有一个类似于文本框的控件由WindowsFormsHost控件托管在我的WPF应用程序中。 Windows窗体控件是ScintillaNET。但我怀疑问题不存在(它在我的旧WinForms项目中工作正常)。
问题在于,当我将文本字段聚焦并尝试聚焦另一个窗口时,窗口会立即抓取焦点。
通过将焦点切换到另一个控件(通过单击)然后切换窗口,我已将此跟踪到文本字段处于焦点。
这有什么解决方法吗?我正在使用MVVM,因此只需将另一个控件设置为代码中的焦点就不是一种选择。
答案 0 :(得分:0)
以下代码按预期工作。也许您可以发布一个示例来重现您的问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using F=System.Windows.Forms;
namespace SimpleForm {
class Window1 : Window {
F.TextBox tb = new F.TextBox();
WindowsFormsHost host = new WindowsFormsHost();
public Window1() {
this.Width = 500;
this.Height = 500;
this.Title = "Title";
host.Child = tb;
Button btn = new Button { Content = "Button" };
StackPanel panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
panel.Children.Add(host);
panel.Children.Add(btn);
this.Content = panel;
btn.Click += delegate {
Window w2 = new Window { Width = 400, Height = 400 };
w2.Content = new TextBox();
w2.Show();
};
}
[STAThread]
static void Main(String[] args) {
F.Application.EnableVisualStyles();
F.Application.SetCompatibleTextRenderingDefault(false);
var w1 = new Window1();
System.Windows.Application app = new System.Windows.Application();
app.Run(w1);
}
}
}
答案 1 :(得分:0)
当前版本的.Net Framework中仍然存在这种“焦点”窃取问题。问题似乎与WindowsFormsHost控件有关,它一旦获得就会永久地窃取焦点(例如,通过点击其中的TextBox控件)。问题可能开始出现在.Net 4.0中,并且可能在4.5中部分修复,但在不同情况下仍然存在。我们发现解决问题的唯一方法是通过Windows API(因为WPF窗口具有与WindowsFormsHost控件分开的hWnd,该控件在窗口中呈现为窗口)。将以下两种方法添加到Window的类中(并在需要重新获取WPF窗口时调用它)有助于解决问题(通过将焦点返回到WPF窗口及其控件)
/// <summary>
/// Native Win32 API setFocus method.
/// <param name="hWnd"></param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SetFocus(IntPtr hWnd);
/// <summary>
/// Win32 API call to set focus (workaround for WindowsFormsHost permanently stealing focus).
/// </summary>
public void Win32SetFocus()
{
var wih = new WindowInteropHelper(this); // "this" being class that inherits from WPF Window
IntPtr windowHandle = wih.Handle;
SetFocus(windowHandle);
}
当从具有WindowsFormsHost控件的页面导航到另一个没有控件的页面时,这也会有所帮助,尽管您很可能需要延迟调用Win32SetFocus(使用{{3 }})。
注意:此代码仅使用x86(32位)版本进行测试,但相同的解决方案应与x64(64位)版本一起使用。如果您需要相同的DLL / EXE代码在两个平台上工作,请改进此代码以加载正确的(32位或64位)非托管DLL。