2017-05-18 3 views
1

WindowsFormsHost에서 호스팅되는 Windows Forms 컨트롤이 있습니다. 내가 양식을 얻기 위해 FindForm 방법을 사용할 수 있기 때문에WindowsFormsHost의 Windows Forms 컨트롤에서 WPF 창 가져 오기

나는 WindowsFormsHost가에있는 창에서 이벤트를 수신 할
<Window x:Class="Forms.Address.MyWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Forms.Address" 
     xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 
     mc:Ignorable="d" 
     Title="New Window" Height="500" Width="720"> 
    <Grid> 
     <WindowsFormsHost x:Name="host"> 
      <local:MyFormsControl x:Name="genericName"/> 
     </WindowsFormsHost> 
    </Grid> 
</Window> 

이 윈도우 형태로 간단하다. 이것은 XAML 내가이 달성하기 위해 사용하는 것입니다 컨트롤이 WindowsFormsHost 내부에있을 때 FindForm이 작동하지 않습니다. 내 컨트롤의 부모는 System.Windows.Forms.Integration.WinFormsAdapter이고 부모는 null입니다.

내 질문은 : 어떻게 내 컨트롤이 들어있는 창을 찾을 수 있습니까?

+0

Process.GetCurrentProcess(). MainWindowHandle'이 도움이 될까요? (당신은 윈도우 클래스에 "MainWindow"라는 이름을 붙 였지만, 정말 응용 프로그램의 메인 윈도우가 될지 확실치 않습니다 ...) 네이티브 윈도우 핸들을 얻음으로써 네이티브 윈도우 이벤트 메시지만을들을 수 있습니다. WPF 관련 이벤트 ... – elgonzo

+0

아니요, 그것은 잘못된 이름이었습니다. 주 창문이 아닙니다. 그래도 좋은 생각. 세부 사항을 제거하기 위해 질문을 변경하겠습니다. –

+0

젠장, 당신은 정말로 그것을 복잡하게 만든다 ;-) 지금 당장 나는 단지 3 가지 다른 가능성에 대해서만 생각할 수있다. (1) 적절한 위치에'new WindowInteropHelper (wpfWindow) .Handle'을 수행하고 얻은 핸들을 어떻게 든 WinForms 컨트롤로 전달합니다. (2) WinFormsAdapter는 내부/문서화되지 않은 클래스 인 것 같습니다. 그러나 아마 당신은 리플렉션을 통해 추출 할 수있는 윈도우 핸들 (또는 다른 유용한 데이터)을 포함하는 필드를 가지고있을 것입니다. (3) WinAPI'EnumChildWindows'를 사용하여 프로세스의 모든 창 핸들을 나열하고 이후의 창 핸들을 식별하는 방법을 찾습니다. – elgonzo

답변

0

필자는 reflection을 사용하여 WinFormsAdapter 클래스에서 필드를 가져올 것을 제안한 elgonzo에게 감사를드립니다. 내가 무슨 짓을

public static Window findParentWindow(Control control) { 
    WindowsFormsHost host = findWPFHost(control); 
    return Window.GetWindow(host); 
}//FindParentWindow 

private static WindowsFormsHost findWPFHost(Control control) { 
    if (control.Parent != null) 
     return findWPFHost(control.Parent); 
    else { 
     string typeName = "System.Windows.Forms.Integration.WinFormsAdapter"; 
     if (control.GetType().FullName == typeName) { 
      Assembly adapterAssembly = control.GetType().Assembly; 
      Type winFormsAdapterType = adapterAssembly.GetType(typeName); 
      return (WindowsFormsHost)winFormsAdapterType.InvokeMember("_host", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance, null, control, new string[0], null); 

     } else 
      throw new Exception("The top parent of a control within a host should be a System.Windows.Forms.Integration.WinFormsAdapter, but that is not what was found. Someone should propably check this out."); 
    }//if 
}//FindWPFHost 

먼저 재귀에서 _host 필드를 추출하는 반사를 사용하는 다음의 WinFormsAdapter을 찾는 것이었다 : 여기 내가 창을 발견하는 방법입니다. WPF WindowsFormsHost 개체이므로 Window.GetWindow(host)을 사용하여 해당 창을 찾을 수 있습니다.

WindowsFormsHost가 ElementHost를 사용하여 Windows Form에 배치되면 GetWindow은 Window가 없으므로 null을 반환합니다.

0

단지 창과 질문에 속성을 추가하고 코드에서 다른 창을 전달하기 만하면됩니다. 이것은 낮은 기술로 들리며 타협으로 살아갈 수 있어야합니다. 100 % Xaml로이를 수행하는 방법을 모릅니다.

이 옵션이 좋지 않으면 다른 옵션 (winapi 등)의 기호성과 비교하십시오. 그것은 당신의 전화 일 수 있습니다!

관련 문제