2013-10-03 33 views
2

我有一个简单的WPF应用程序MyWPF.exe,如何使用反射

namespace MyWPF 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    {   

    public MainWindow() 
    { 
     InitializeComponent(); 

    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
    MessageBox.Show("Button is clicked"); 
    } 
    } 
} 

我想在我的WinForm应用程序加载这个“主窗口”在WinForm的主机WPF应用程序,我试图像下面,我得到当创建实例为“”时发生异常“System.InvalidOperationException:窗口必须是树的根,不能将Window添加为Visual的子项。”

 String path = @"D:\Test\MyForm\MyWPF\bin\Debug\MyWPF.exe"; 
     System.Reflection.Assembly myExeApp = System.Reflection.Assembly.LoadFile(path); 
     System.Type MyWPFType = myExeApp.GetType("MyWPF.MainWindow"); 

     var MyWPFInstance = (System.Windows.Window)myExeApp.CreateInstance("MyWPF.MainWindow"); 

     ctrlHost = new ElementHost(); 
     ctrlHost.Dock = DockStyle.Fill; 
     ElementHost.EnableModelessKeyboardInterop(MyWPFInstance); 
     ctrlHost.Child = MyWPFInstance ; 
     this.Controls.Add(ctrlHost); 

是否有可能或缺少一些东西?整个例外情况如下,

System.InvalidOperationException: Window must be the root of the tree. Cannot add Window as a child of Visual. 
    at System.Windows.Window.OnAncestorChanged() 
    at System.Windows.FrameworkElement.OnAncestorChangedInternal(TreeChangeInfo parentTreeState) 
    at System.Windows.TreeWalkHelper.OnAncestorChanged(DependencyObject d, TreeChangeInfo info) 
    at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) 
    at MS.Internal.PrePostDescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) 
    at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation) 
    at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent) 
    at System.Windows.FrameworkElement.AddLogicalChild(Object child) 
    at System.Windows.Controls.UIElementCollection.AddInternal(UIElement element) 
    at System.Windows.Controls.UIElementCollection.Add(UIElement element) 
    at System.Windows.Forms.Integration.ElementHost.set_Child(UIElement value) 
    at MyForm.Form1.button1_Click(Object sender, EventArgs e) in D:\Test\MyForm\MyForm\Form1.cs:line 37 
    at System.Windows.Forms.Control.OnClick(EventArgs e) 
    at System.Windows.Forms.Button.OnClick(EventArgs e) 
    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
    at System.Windows.Forms.Button.WndProc(Message& m) 
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
+0

这听起来像你不能把一个窗口内的控件。似乎很合理。为什么不使用其他类型的容器而不是向控制主机添加*窗口?网格或其他面板可能? – sircodesalot

+0

但我可以在Winform里面用Winform做到这一点。 – Dev

+0

我当然不怀疑,但是如果你打算完全重新设计一个API(比如WPF),你可能会考虑约束那些在技术上没有意义的东西(比如把窗口放在窗口内)。此外,如果它不允许你使用Window,你可以改变你的窗口从'UserControl'(而不是'Window')派生,并且解决问题。 – sircodesalot

回答

2

ElementHost不适用于这种互操作。您可以使用任何非Window控件作为其子。您可以重构您的WPF应用程序,使主窗口包含只有用户控件,您将使用反射代码加载并添加到窗体。

或者,您可以使用Win32 SetParent将WPF窗口作为Windows窗体控件的子窗口,但我绝对会避免这种情况。

+0

我只想尝试,以及如何做到这一点? – Dev