2014-09-05 7 views
0

WindowsFormsHost 컨트롤에 의해 WPF 응용 프로그램에서 호스팅되는 텍스트 상자 컨트롤과 같은 컨트롤이 있습니다. 윈도우 폼 컨트롤은 ScintillaNET입니다. 하지만 문제가 없다고 생각합니다 (이전의 WinForms 프로젝트에서 문제없이 작동하고있었습니다).WindowsFormsHost forces 포커스

문제는 텍스트 필드가 초점을 맞추고 다른 창을 집중 시키려고 할 때 창 바로 뒤에 초점을 맞 춥니 다.

포커스를 다른 컨트롤 (클릭)을 통해 전환하고 창을 전환하여 포커스가있는 텍스트 필드를 추적했습니다.

해결 방법이 있습니까? 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- 탭하거나 열 수 있습니까? (WinForms 텍스트 상자에는 포커스가 있습니다) ? ScintillaNET이 내 상황에 의해 드러난 해킹을 할 수도 있습니다. –

+0

예, alt + 탭과 작업 표시 줄 모두 정상적으로 작동합니다. – Loathing

+0

호스트가 제대로 처리하지 못하는 이상한 물건을 ScintillaNET에서 수행해야합니다. –

0

"포커스"도용 문제는 .Net Framework의 현재 버전에도 계속 존재합니다. 문제는 WindowsFormsHost 컨트롤과 관련이있는 것 같습니다 (예를 들어 TextBox 컨트롤을 클릭하여 포커스를 가져 오면 영구히 훔치는 컨트롤). 아마 .Net 4.0에 등장하기 시작한 이슈는 4.5에서 부분적으로 수정되었을 수도 있지만, 다른 시나리오에서는 여전히 존재합니다. 문제를 해결하는 유일한 방법은 Windows API를 사용하는 것입니다 (WPF 창은 창 내부의 창으로 렌더링되는 WindowsFormsHost 컨트롤과 별도의 hWnd를 가짐). 윈도우의 클래스에 다음과 같은 2 가지 방법을 추가 (그리고 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); 
    } 

이것은 또한 때 도움이 될 것입니다 (WPF 창 및 해당 컨트롤에 포커스를 반환하여) 문제를 해결하는 데 도움이 WindowsFormsHost 컨트롤을 가지고있는 페이지에서 다른 페이지로 이동하는 것이지만, 지연이있는 Win32SetFocus (DispatcherTimer 사용)를 호출 할 필요가 있습니다.

참고 :이 코드는 단지 구축의 x86 (32 비트)에서 테스트했지만, 같은 솔루션은 64 (64 비트) 빌드와 함께 작동합니다. 두 플랫폼 모두에서 동일한 DLL/EXE 코드가 필요하면이 코드를 개선하여 적절한 (32 비트 또는 64 비트) 비 관리 DLL을로드하십시오.