Окно WPF из консольного проекта? - PullRequest
14 голосов
/ 26 января 2009

Я недавно начал проект C # (VS 2008) как проект 'Консоль', где я написал несколько библиотек, тестовых программ и т. Д. Теперь я хотел бы добавить пару окон WPF, но это похоже на консольный проект. не позволит мне сделать это Я прихожу с Java, так что это немного странно. Как я могу добавить форму WPF (которую я сам создаю из своего «основного» класса?

Ответы [ 5 ]

38 голосов
/ 03 апреля 2009

Принятый ответ не совсем верен, боюсь, просто добавьте атрибут [STAThread] перед вашим mainmethod и сделайте ссылки на нужные библиотеки (например, System.Windows), и все готово для добавления окон wpf.

РЕДАКТИРОВАТЬ: в комментариях @JamesWilkins предоставил мне эту полезную ссылку: http://code -phix.blogspot.be / 2013/11 / creation-wpf-project-from-scratch.html

24 голосов
/ 30 октября 2015

У меня был тот же вопрос, и я искал похожий ответ. Я нашел информацию повсюду, поэтому я кладу то, что нашел, в одно место. Мне также нужен был способ скрыть и показать окно консоли, поэтому я обнаружил, что это работает (для VS 2013 +):

  1. Создайте новый консольный проект (обязательно выберите нужную версию .NET Framework - мне нужно было использовать .Net 4.0 сам). Убедитесь, что у вас есть следующие ссылки:

    • PresentationFramework
    • PresentationCore
    • WindowsBase
    • System.xaml
  2. Щелкните правой кнопкой мыши проект в обозревателе решений, выберите «Свойства» и измените Тип вывода проекта на Приложение Windows. Это предотвращает отображение окна консоли при запуске (если вы хотите, пропустите этот шаг).

  3. Хотя управление окном консоли необязательно для добавления окон WPF, это может быть полезно. Если вам это не нужно, перейдите к # 4. В классе «Program» для консоли добавьте это, чтобы управлять окном:

    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 должен работать в однопоточных квартирах .

      [STAThread]
      static void Main(string[] args)
      {
      }
    
  5. Добавление окна: Чтобы сделать это, просто добавьте пользовательский элемент управления в свой проект и назовите его «MainWindow» (или как вам угодно). Просто щелкните правой кнопкой мыши узел проекта в обозревателе решений и выберите Add->User Control.... Откройте код MainWindow.xaml.cs и измените MainWindow : UserControl на MainWindow : Window. Затем откройте файл MainWindow.xaml и измените первый тег <UserControl на <Window (и убедитесь, что закрывающий тег также переименован, что должно быть автоматически при использовании Visual Studio). Закройте все вкладки редактора «MainWindow» и откройте заново (просто чтобы убедиться, что в этом нет необходимости). Вы должны увидеть, что 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...");
    }
    

Надеюсь, это поможет сэкономить время, ура! ;)

СОВЕТ: в моем случае было полезно позвонить InitializeWindows() в новой теме; однако это означает, что вы должны создавать объекты пользовательского интерфейса (среди прочего) в том же потоке, в котором был создан объект Application. Для связи с новым потоком я просто использовал класс Dispatcher (WinApp.Dispatcher.BeginInvoke()) запускать запросы в контексте потока WPF.

Для Windows 8/10: если вы отлаживаете и не видите текста в окне вывода, посмотрите здесь: https://stackoverflow.com/a/49145317/1236397

3 голосов
/ 26 января 2009

Вы должны переместить код своей библиотеки в другой проект «Библиотека классов» и использовать его из своего проекта консоли. Ваши окна WPF должны быть в другом проекте "Приложение WPF", который также будет ссылаться на вашу "Библиотеку классов".

0 голосов
/ 26 января 2009

Благодаря aku и Дмитрию я создаю еще один проект (WPF), который будет ссылаться на мой консольный код.

0 голосов
/ 26 января 2009

Вы уверены, что вам нужен консольный проект? Вы можете создать проект «Приложение WPF» и добавить ссылки на свои библиотеки и т. Д. Если вы попытаетесь отобразить окно WPF из консольного приложения, вы получите исключение из-за различий в модели потоков между приложениями Console и WPF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...