我有一个类似文本框的控件,它由WindowsFormsHost控件承载在我的WPF应用程序中。windows窗体控件为ScintillaNET。但我怀疑问题并不在那里(它在我以前的WinForms项目中运行得很好)。
问题是,当我将文本字段聚焦时,当我试图聚焦另一个窗口时,该窗口会立即抓住焦点。
通过将焦点切换到另一个控件(通过单击),然后切换窗口,我已经跟踪到文本字段处于焦点中。
有什么解决方法吗?我使用的是MVVM,所以在代码中简单地将另一个控件设置为焦点是不可行的。
发布于 2017-10-23 23:34:08
这种“焦点”窃取问题仍然存在于当前版本的.Net框架中。问题似乎与WindowsFormsHost控件有关,该控件一旦获得焦点(例如,通过单击其中的TextBox控件),它就会永久窃取焦点。问题可能在.Net 4.0中开始出现,并可能在4.5中部分修复,但在不同的情况下仍然存在。我们发现解决这个问题的唯一方法是通过Windows API (因为WPF窗口具有独立于WindowsFormsHost控件的hWnd,该控件呈现为窗口中的窗口)。向窗口的类添加以下两个方法(当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 (使用DispatcherTimer。
注意:这段代码只在x86 (32位)版本上进行了测试,但同样的解决方案也可以在x64 (64位)版本上运行。如果您需要相同的DLL/EXE代码才能在两个平台上工作,请改进此代码以加载正确的(32位或64位)非托管DLL。
发布于 2014-09-05 13:16:12
下面的代码按预期工作。也许你可以发布一个例子来重现你的问题。
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);
}
}
}https://stackoverflow.com/questions/25678512
复制相似问题