来自Console项目的WPF窗口?

时间:2009-01-26 07:04:48

标签: c# wpf console

我最近开始将一个C#项目(VS 2008)作为一个“控制台”项目,我写了一些库,测试程序等。现在我想添加几个WPF窗口,但它看起来像控制台项目不会让我这样做的。我来自Java所以这有点奇怪。如何添加WPF表单(我将从我的“主”类中实例化我自己?

5 个答案:

答案 0 :(得分:38)

接受的答案并不完全正确,我担心,只需在mainmethod之前添加[STAThread]属性并引用正确的库(如System.Windows),你就可以添加wpf windows了。

编辑:@JamesWilkins在评论中为我提供了这个有用的链接:http://code-phix.blogspot.be/2013/11/creating-wpf-project-from-scratch.html

答案 1 :(得分:24)

我有同样的问题,正在寻找类似的答案。我发现了整个地方的信息,所以我把我在一个地方找到的东西放进去了。我还需要一种隐藏和显示控制台窗口的方法,所以我发现这有效(对于VS 2013 +):

  1. 创建一个新的控制台项目(确保选择您需要使用的.NET框架版本 - 我需要自己使用.Net 4.0)。确保有以下参考:

    • PresentationFramework
    • PresentationCore
    • WindowsBase
    • System.xaml
  2. 右键单击解决方案资源管理器中的项目,然后选择     "属性",并将项目输出类型更改为Windows应用程序。     这可以防止控制台窗口在启动时显示(如果您     希望如此,跳过这一步。)

  3. 虽然为了添加WPF窗口不需要控制控制台窗口,但它可能很有用。如果您不需要,请跳至#4。在"计划"控制台的类,添加它以控制窗口:

    public class Program
    {
      [DllImport("kernel32.dll", SetLastError = true)]
      static extern bool AllocConsole(); // Create console window
    
      [DllImport("kernel32.dll")]
      static extern IntPtr GetConsoleWindow(); // Get console window handle
    
      [DllImport("user32.dll")]
      static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
      const int SW_HIDE = 0;
      const int SW_SHOW = 5;
    

    这允许创建,隐藏和显示控制台窗口。我创建了这些方法:

      static void ShowConsole()
      {
          var handle = GetConsoleWindow();
          if (handle == IntPtr.Zero)
              AllocConsole();
          else
              ShowWindow(handle, SW_SHOW);
      }
    
      static void HideConsole()
      {
          var handle = GetConsoleWindow();
          if (handle != null)
              ShowWindow(handle, SW_HIDE);
      }
    

    这些大多是自解释的,但如果项目处于窗口模式,GetConsoleWindow();返回null,那么我们在这里测试句柄是否为空(在这种情况下为零),如果是,需要创建一个控制台窗口(仅一次)。在此之后,GetConsoleWindow();将始终返回要使用的句柄。

  4. 正如另一个答案中所述,您需要在控制台[STAThread]方法之前的一行添加Main。这是必需的,因为WPF需要在Single Threaded Apartment环境中运行。

      [STAThread]
      static void Main(string[] args)
      {
      }
    
  5. 添加窗口:要执行此操作,只需将用户控件添加到项目中并将其命名为&#34; MainWindow&#34; (或任何你喜欢的)。只需右键单击解决方案资源管理器中的项目节点,然后选择Add->User Control...。打开后面的MainWindow.xaml.cs代码,将MainWindow : UserControl更改为MainWindow : Window。接下来,打开MainWindow.xaml文件并将第一个标记<UserControl更改为<Window(并确保重命名结束标记,如果使用Visual Studio,则应自动重命名)。关闭所有&#34; MainWindow&#34;编辑器选项卡并重新打开(只是为了确保,可能没有必要)。您应该看到MainWindow.xaml现在在设计窗格中显示一个窗口。

  6. 显示WPF窗口:为此,我们需要启动窗口消息循环,这非常简单。首先,我创建了一些属性来存储对象。把它放在Program类的某个地方。

    public static Application WinApp { get; private set; }
    public static Window MainWindow { get; private set; }
    

    接下来,我们必须通过创建System.Windows.Application对象来创建消息循环,然后将其传递给主窗口。我创建了这个方法来执行这个任务:

    static void InitializeWindows()
    {
        WinApp = new Application();
        WinApp.Run(MainWindow = new MainWindow()); // note: blocking call
    }
    

    那就是它!要对此进行测试,请在主窗口中放置一些内容并执行以下操作:

    [STAThread]
    static void Main(string[] args)
    {
        ShowConsole(); // Show the console window (for Win App projects)
        Console.WriteLine("Opening window...");
        InitializeWindows(); // opens the WPF window and waits here
        Console.WriteLine("Exiting main...");
    }
    
  7. 希望有助于节省时间,欢呼! ;)

    提示:在我的案例中,我发现在新线程中调用InitializeWindows()会很有帮助;但是,这意味着您必须在创建Application对象的同一个线程中创建UI对象(以及其他内容)。为了与新线程通信,我只使用了Dispatcher类( WinApp.Dispatcher.BeginInvoke())在WPF线程上下文中运行请求。

    对于Windows 8/10:如果您正在调试但未在输出窗口中看到任何文字,请查看此处:https://stackoverflow.com/a/49145317/1236397

答案 2 :(得分:3)

您应该将库代码移动到其他“类库”项目,并在Console项目中使用它。您的WPF窗口应该在另一个“WPF应用程序”项目中,该项目也将引用您的“类库”。

答案 3 :(得分:0)

您确定需要Console项目吗?您可以创建“WPF应用程序”项目并添加对库等的引用。如果尝试从控制台应用程序显示WPF窗口,由于控制台和放大器之间的线程模型不同,您将产生异常。 WPF应用程序。

答案 4 :(得分:0)

感谢aku和Dmitriy,我创建了另一个项目(WPF),它将引用我的基于控制台的代码。

相关问题