2009-01-26 12 views
11

Recientemente comencé un proyecto C# (VS 2008) como un proyecto 'Consola' donde escribí algunas bibliotecas, programas de prueba, etc. Ahora me gustaría agregar un par de ventanas WPF, pero parece que el proyecto de la consola ganó No me dejes hacer eso. Vengo de Java, así que esto es un poco extraño. ¿Cómo puedo agregar un formulario WPF (que me creará una instancia de mi clase "principal"?Ventana de WPF de un proyecto de consola?

Respuesta

0

¿Está seguro de que necesita un proyecto de consola? Puede crear un proyecto de "aplicación WPF" y agregar referencias a sus bibliotecas, etc. Si intenta mostrar la ventana de WPF desde la aplicación de la consola generará una excepción debido a diferencias en el modelo de subprocesamiento entre las aplicaciones WPF de la consola &

+4

[STAThread] atributo para el método principal lo hace posible! –

3

Debería mover el código de su biblioteca a otro proyecto de "biblioteca de clases" y usarlo desde su consola proyecto. Sus ventanas WPF deben estar en otro proyecto de "aplicación WPF" que también hará referencia a su "biblioteca de clases".

0

Gracias a aku y Dmitriy, creo otro proyecto (W PF) que hará referencia a mi código basado en la consola.

37

La respuesta aceptada no es del todo cierta, me temo, simplemente agregue el atributo [STAThread] antes de su método principal y haga referencias a las bibliotecas correctas (como System.Windows) y ya está listo para agregar wpf windows .

EDIT: En los comentarios @JamesWilkins me suministran con este enlace útil: http://code-phix.blogspot.be/2013/11/creating-wpf-project-from-scratch.html

+0

¡Tienes razón, Peter! –

+0

La respuesta aceptada es teóricamente cierta. Todo lo que pregunta es si está seguro de que realmente necesita una aplicación de consola. Pero debo aceptar que me gusta más tu respuesta como respuesta a este problema exacto. –

+0

El enlace no funciona. –

14

que tenía la misma pregunta y estaba buscando una respuesta similar. Encontré información en todo el lugar, así que pongo lo que encontré en un solo lugar. También necesitaba una manera de ocultar y mostrar la ventana de la consola, por lo que descubrí esto funcionó (para VS 2013+):

  1. Crear un nuevo proyecto de consola (asegúrese de seleccionar la versión del marco .NET que necesita usar, necesitaba usar .Net 4.0 yo mismo). Asegúrese de tener las siguientes referencias:

    • PresentationFramework
    • PresentationCore
    • WindowsBase
    • System.xaml
  2. Haga clic derecho en el proyecto en el explorador de soluciones, seleccione " Propiedades ", y cambie el tipo de salida del proyecto a la aplicación de Windows. Esto evita que la ventana de la consola se muestre al inicio (si desea , omita este paso).

  3. Si bien el control de la ventana de la consola no es necesario para agregar ventanas WPF, puede ser útil. Si no necesita esto, salte al # 4. En la categoría "Programa" para la consola, agregue esto a fin de controlar la ventana:

    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; 
    

    Esto permite crear, ocultar y mostrar la ventana de la consola. He creado estos métodos para hacer esto:

    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); 
        } 
    

    Estos son en su mayoría explica por sí mismo, pero si el proyecto se encuentra en modo de ventana, GetConsoleWindow(); vuelve null, por lo que aquí probar si el mango es nula (cero en este caso), y si es así, se debe crear una ventana de consola (solo una vez). Después de esto, GetConsoleWindow(); siempre devolverá un identificador para usar.

  4. Como se ha dicho en otra respuesta ya, necesidad de añadir [STAThread] en una línea antes de que el método de la consola Main. Esto es obligatorio, ya que WPF necesita ejecutarse en un entorno Single Threaded Apartment.

    [STAThread] 
        static void Main(string[] args) 
        { 
        } 
    
  5. Adición de una ventana: Para ello, basta con agregar un control de usuario a su proyecto y el nombre "MainWindow" (o lo que quieras). Simplemente haga clic con el botón derecho en el nodo del proyecto en el explorador de soluciones y seleccione Add->User Control.... Abra el código MainWindow.xaml.cs detrás y cambie MainWindow : UserControl al MainWindow : Window. A continuación, abra el archivo MainWindow.xaml y cambie la primera etiqueta <UserControl a <Window (y asegúrese de que también se cambie el nombre de la etiqueta de cierre, que debería ser automática si se usa Visual Studio). Cierre todas las pestañas del editor de "MainWindow" y vuélvalas a abrir (solo para estar seguro, puede que no sea necesario). Debería ver que MainWindow.xaml ahora muestra una ventana en el panel de diseño.

  6. Mostrando la ventana de WPF: Para hacer esto, tenemos que iniciar el bucle de mensajes de la ventana, que es realmente fácil. Para comenzar, creé algunas propiedades para almacenar los objetos. Solo ponga esto en algún lugar de la clase Program.

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

    A continuación tenemos para crear el mensaje de bucle mediante la creación de un objeto System.Windows.Application, a continuación, pasar la ventana principal. Creé este método para realizar esta tarea:

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

    y eso es todo! Para probar esto, poner un poco de contenido en la ventana principal y hacer esto:

    [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..."); 
    } 
    

Esperanza que ayuda a ahorra tiempo a alguien, saludos! ;)

CONSEJO: Me ha parecido útil, en mi caso, llamar al InitializeWindows() en un nuevo hilo; sin embargo, eso significa que debe crear objetos UI (entre otras cosas) en el mismo subproceso en el que se creó el objeto Application. Para comunicarse con el nuevo subproceso, acabo de utilizar la clase Dispatcher (WinApp.Dispatcher.BeginInvoke()) para ejecutar solicitudes en WPF contexto de hilo.

Para Windows 8/10: Si está depurando y no ve ningún texto en la ventana de salida, echar un vistazo aquí: https://stackoverflow.com/a/49145317/1236397

+2

Respuesta sorprendente y completa. ¿Por qué no más votaciones? –

Cuestiones relacionadas