代码之家  ›  专栏  ›  技术社区  ›  Ievgen

强制WinForms Application.Run方法使用WPF表单

  •  0
  • Ievgen  · 技术社区  · 11 年前

    我有一个现有的WinForms应用程序。 在这个应用程序中,一个表单在单独的线程中被调用:

     var newDialogThread = new Thread(new ThreadStart(ShowMyForm));
     newDialogThread .Name = "CustomerViewThread";
     newDialogThread .IsBackground = true;
     newDialogThread .ApartmentState = ApartmentState.STA;
     newDialogThread .CurrentCulture = Config.CustomerCulture;
    
    public void ShowMyForm()
    {
      using(var myForm = new MyForm())
      {
         Application.Run(myForm );
       }
    }
    

    现在客户希望使用WPF表单而不是WinForms对话框。应用程序将保持基于Winforms。

    如何正确地重构这部分代码,以便调用我的WPF表单而不是Winforms?

     public void ShowMyForm()
        {
          using(var myWpfForm = new MyWpfForm())
          {
              // Analog of Application Run?
             //Application.Run(myForm );
           }
        }
    

    附言:我认为可以创建纯WPF窗口,而无需将其托管到Winforms。这是主要情况。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Sheridan    11 年前

    听起来你需要编辑你的( WinForms ) MyForm 控件添加 ElementHost 控件,以便它可以承载您的WPF控件:

    MyWpfForm myWpfForm = new MyWpfForm();
    ElementHost elementHost = new ElementHost();
    elementHost.Child = myWpfForm;
    this.Controls.Add(elementHost);
    

    这样,你就可以把你的 ShowMyForm 方法不变。

        2
  •  1
  •   Rhys Towey    11 年前

    This article 解释了如何做到这一点。但基本上:

    1) 创建/添加类型为“WPF自定义控件库”的新项目

    2) 添加类型为“窗口(WPF)”的新项

    3) 使用WPF窗口执行您的操作

    4) 从WinForms应用程序中,创建并打开WPF窗口:

    using System;  
    using System.Windows.Forms;  
    using System.Windows.Forms.Integration;  
    
    //Place the following code where you want to open the WPF window
    var wpfwindow = new WPFWindow.Window1(); 
    ElementHost.EnableModelessKeyboardInterop(wpfwindow); 
    wpfwindow.Show();
    
        3
  •  0
  •   Ievgen    6 年前

    我在相关的帖子中找到了答案: How do I create and show WPF windows on separate threads?

      private void NewWindowHandler(object sender, RoutedEventArgs e)
    {       
        Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
        newWindowThread.SetApartmentState(ApartmentState.STA);
        newWindowThread.IsBackground = true;
        newWindowThread.Start();
    }
    
    private void ThreadStartingPoint()
    {
        Window1 tempWindow = new Window1();
        tempWindow.Show();       
        System.Windows.Threading.Dispatcher.Run();
    }
    

    http://msdn.microsoft.com/en-us/library/ms741870.aspx