2014-09-05 72 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。