2009-01-26 2 views
11

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

ответ

0

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

+4

[STAThread] атрибут для главного метода делает это возможным! –

3

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

0

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

37

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

EDIT: в комментариях @JamesWilkins снабжал меня по этой ссылке: ПОЛЕЗНЫЕ http://code-phix.blogspot.be/2013/11/creating-wpf-project-from-scratch.html

+0

Вы правы Петр! –

+0

Принятый ответ теоретически справедлив. Все, что он спрашивает, если он уверен, что ему действительно нужно консольное приложение. Но я должен согласиться с тем, что мне нравится ваш ответ лучше, как ответ на эту конкретную проблему. –

+0

Ссылка не работает. –

14

У меня был тот же вопрос и искал подобный ответ. Я нашел информацию повсюду, поэтому я помещаю то, что нашел в одном месте. Я также нужен способ, чтобы скрыть и показать окно консоли, так что я узнал, что это работает (для 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. Добавление окна: Чтобы сделать это, просто добавьте пользовательский элемент управления для вашего проекта и назовите его «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

+2

Удивительный и тщательный ответ. Почему бы не увеличить количество оборотов? –

Смежные вопросы