2014-09-05 80 views
0

我有一个文本框控件在我的WPF应用程序由WindowsFormsHost控件托管。窗体控件是ScintillaNET。但我怀疑问题不存在(它在我的旧WinForms项目中工作正常)。WindowsFormsHost力量焦点

问题是,当我将文本字段聚焦并且我尝试将焦点放在另一个窗口时,窗口紧随其后聚焦。

我已经通过将焦点切换到另一个控件(通过点击)然后切换窗口来追踪到焦点所在的文本字段。

有没有解决方法?我正在使用MVVM,因此只需将另一个控件设置为代码中的焦点不是一种选择。

回答

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); 
    } 
} 
} 
+0

因此,当第一个窗口上的文本框打开并且您已经打开了另一个窗口时,是否可以直接在任务栏上打开或打开该窗口(而WinForms文本框具有焦点) ?这可能是因为ScintillaNET做了一些我的情况所揭示的黑客行为。 – 2014-09-05 05:37:34

+0

是的,ALT +选项卡和任务栏都正常工作。 – Loathing 2014-09-05 05:47:29

+0

必须只是ScintillaNET做一些主机无法正确处理的奇怪东西。 – 2014-09-06 08:01:57

0

这种“焦点”盗取问题在当前版本的.Net Framework中仍然存在。问题似乎与WindowsFormsHost控制有关,该控件一旦获取就会永久性地窃取焦点(例如通过单击其中的TextBox控件)。问题可能开始出现在.Net 4.0中,并可能在4.5中部分修复,但在不同情况下仍然存在。我们发现通过Windows API解决问题的唯一方法就是通过Windows API(因为WPF窗口与WindowsFormsHost控件分开的hWnd在窗口内呈现为窗口)。添加下列2种方法来窗口的类(并调用它,当需要进行恢复焦点的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。