2014-09-05 4 views
0

У меня есть текстовое поле, такое как элемент управления, размещенный в моем приложении WPF с помощью элемента управления WindowsFormsHost. Элементом управления окнами является ScintillaNET. Но я подозреваю, что проблема не там (она отлично работала в моем старом проекте WinForms).WindowsFormsHost force Focus

Проблема в том, что когда у меня есть текстовое поле, сфокусированное, и я пытаюсь сфокусировать другое окно, окно сразу же захватывает фокус.

Я отследил это до текстового поля, находящегося в фокусе, переключив фокус на другой элемент управления (через щелчок), а затем переключая окна.

Есть ли обходной путь для этого? Я использую 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

Итак, когда вы открываете текстовое поле в первом окне, и у вас уже есть другое окно, вы можете прямо нажимать alt-tab или открывать это окно на панели задач (в то время как текстовое поле WinForms имеет фокус) ? Возможно, ScintillaNET делает некоторые хаки, которые раскрываются моими обстоятельствами. –

+0

Да, alt + вкладка и панель задач работают нормально. – Loathing

+0

Должно быть, только ScintillaNET делает некоторые странные вещи, которые Хост неправильно обрабатывает. –

0

Этот вид проблемы «фокуса» по-прежнему существует в текущей версии .Net Framework. Проблема, похоже, связана с управлением WindowsFormsHost, которое постоянно крадет фокус после его получения (например, нажав на элемент управления TextBox внутри него). Вероятно, проблема возникла в .NET 4.0 и, вероятно, частично была зафиксирована в 4.5, но в разных сценариях все еще существует. Единственный способ найти проблему - через Windows API (поскольку в окне WPF есть отдельный hWnd из элемента управления WindowsFormsHost, который отображается как окно в окне). Добавление 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).

Примечание: Этот код был протестирован только с х86 (32-х) строить, но то же самое решение должно работать с x64 (64-бит) сборки. Если вам нужен один и тот же код DLL/EXE для работы на обеих платформах, улучшите этот код, чтобы загрузить надлежащую (32-битную или 64-битную) неуправляемую DLL.

 Смежные вопросы

  • Нет связанных вопросов^_^