none
How to open a Form with Console application? RRS feed

  • Question

  • Hi,
    Could some one come and explain how to open a form with console application.
    Imagine, you wrote an application in console mode and ask a user to press "w" to show the specific form.
    I'd really appriciated, if some one give me an example!
    Thanks
    Memphis
    Saturday, September 1, 2007 12:40 AM

Answers

  • Well, not quite straight forward.

     

    You need to create a Windows application. Then right click the project and go to properties and set the Output Type for the application to Console Application. This will then not only show your form but also the Console Window. So now you can use the Console class to read in or display messages to that console Window.

     

    Of course, the problem here for you would be that the Form will always show. I guess you can move the Application.Run(new Form1()); line in the program.cs file to the appropriate place when reading inputs etc... and see if this helps you. From here you can then proceed to develop your application and create/load forms from the console Window from user input.

     

    Does this help?

    Saturday, September 1, 2007 12:55 AM
    Moderator
  • To the OP:

    This is how you can display a form from a class library from within a Console app:
    1. Create a class library. Let's call the assembly "ClassLibraryWithForm".
      (Here I must point out that when you create a default class library, a reference to the System.Windows.Forms assembly is automatically added to the project because, yes, Microsoft are expecting you to be able to add some Forms stuff to the class library.)
    2. Add a form to the class library. Let's call it MyTestForm. Put a test button on the form and wire it up to a handler that just displays a message box.
    3. Compile the class library.
    4. Create a default Console App.
    5. To the console app, add a reference to System.Windows.Forms.
    6. Also add a reference to your class library created in step (1).
    7. Add to the top of  Program.CS:     using System.Windows.Forms;
    8. Change the Main() method to look like the following, then compile and run it. Press return when prompted to display the form. Click the test button and see the test message.


    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new ClassLibraryWithForm.TestForm());
    }

     


    NOTE: That doesn't show you how to communicate with the form at runtime; to do so, you'd need another thread to do the work and call methods in the form that you expose. I'll post another message in a few mins to show you how to do so.


    Tuesday, September 4, 2007 12:06 PM
  • Example Continued: How to change the form's data from the console app:

    1. Add to the form in the class library a TextBox. Call it 'testTextBox'.
    2. Add this code to the form:



    private delegate void UpdateTextBoxDelegate(string newText);

    public void UpdateTextBox(string newText)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), new object[]{newText});
        }
        else
        {
            testTextBox.Text = newText;
        }
    }

     


    3. Change the code in the console app as follows:



    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        ClassLibraryWithForm.TestForm testForm = new ClassLibraryWithForm.TestForm();

        System.Threading.Thread worker = new System.Threading.Thread(DoWork);
        worker.Start(testForm);

        Application.Run(testForm);
    }

    private static void DoWork(object formObject)
    {
        ClassLibraryWithForm.TestForm form = formObject as ClassLibraryWithForm.TestForm;

        for (int i=0; i<=30; ++i)
        {
            form.UpdateTextBox(i.ToString());
            System.Threading.Thread.Sleep(1000);
        }
    }

     


    4. Now when you run the program, the text in the form's textbox will count up to 30.

    Tuesday, September 4, 2007 12:24 PM
  • Final example: Putting the form into a separate thread in the console app (this is an alternative to the previous example):



    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        ClassLibraryWithForm.TestForm testForm = new ClassLibraryWithForm.TestForm();

        System.Threading.Thread formShower = new System.Threading.Thread(ShowForm);
        formShower.Start(testForm);

        for (int i=0; i<30; ++i)
        {
            if (testForm.IsDisposed)
            {
                Console.WriteLine("Form disposed, exiting.");
                break;
            }

            Console.WriteLine(i.ToString());
            testForm.UpdateTextBox(i.ToString());
            System.Threading.Thread.Sleep(1000);
        }
    }

    private static void ShowForm(object formObject)
    {
        ClassLibraryWithForm.TestForm form = formObject as ClassLibraryWithForm.TestForm;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(form);
    }

     


    Tuesday, September 4, 2007 12:40 PM

All replies

  • Well, not quite straight forward.

     

    You need to create a Windows application. Then right click the project and go to properties and set the Output Type for the application to Console Application. This will then not only show your form but also the Console Window. So now you can use the Console class to read in or display messages to that console Window.

     

    Of course, the problem here for you would be that the Form will always show. I guess you can move the Application.Run(new Form1()); line in the program.cs file to the appropriate place when reading inputs etc... and see if this helps you. From here you can then proceed to develop your application and create/load forms from the console Window from user input.

     

    Does this help?

    Saturday, September 1, 2007 12:55 AM
    Moderator
  • Hi Thanks for replaying!
    But the problem is, I made a dll file and When I use that dll in my application, I want to show the form that inside the DLL file. I can show that form, but it's just freezed!
    Do I have to use invoke? How can I handle the message window?
    Very simple program can help me!

    Thanks
    Memphis
    Saturday, September 1, 2007 1:03 AM
  •  

    Really you shouldnt be embedding a form and showing in an assembly, should really be in the exe file.

    Are you able to debug and see whats going on when you are showing the form? Have you tried what I suggested earlier? What code are you using?

    Saturday, September 1, 2007 1:10 AM
    Moderator
  • Let's make a simple example,
    I opened the visual studio 2005 and I went to visaul C# section and select windows an finally select class Library.
    Then I add one windows form into my Dll project. I called it Form1.
    finally I compiled it. So now I have a Dll file that contains a form.
    Then I create another application, console or windows.
    add that dll in my resource
    and now I have access to that dll and functions.
    Now How can I show that form in diffrent thread?
    Do I have to use windows application in order to show the form or there is a way to show that form in Console mode?

    I hope you undrestand what am I saying
    Thanks
    Memphis
    Saturday, September 1, 2007 1:20 AM
  • Hi,

    try to use process.start or winexec you can run windows application from console and vice versa...

     

    Regards,

    Saturday, September 1, 2007 1:29 AM
  • Hi, Thank you for reapling,
    but the thing is, I want to control that form from that console! I hope that make sence!
    I have thread that process something in background, and I want to update that form  by new data that I process in background. So, now what am I suppose to do?
    remember: I want to open a form from that dll and update it from my new data in console mode!
    Thanks
    Memphis
    Saturday, September 1, 2007 1:36 AM
  • Hi Again,

    Sorry for late,

    Add a new console project and use the following code:

    Code Snippet

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Windows.Forms;

    using System.Drawing;

    using System.ComponentModel;

    namespace Test

    {

    class Program

    {

    static void Main(string[] args)

    {

    FormDemo.View();

    }

    }

    class FormDemo : Form

    {

    static string[] strCaption ={ "BorderLess Window", "AutoScroll Window", "Sized Window", "Uncloseable", "Not in TaskBar" };

    Button[] btnShow = new Button[strCaption.Length];

    public FormDemo()

    {

    this.Text = "Demonstration of Winform";

    this.MaximumSize = new Size(300, 300);

    this.MinimumSize = new Size(300, 300);

    this.StartPosition = FormStartPosition.CenterScreen;

    this.Load += new EventHandler(Form_Load);

    this.Closing += new CancelEventHandler(Form_Closing);

    for (int i = 0; i < strCaption.Length; i++)

    {

    btnShow[i] = new Button();

    btnShow[i].Text = strCaption[i];

    btnShow[i].Size = new Size(200, 20);

    btnShow[i].Location = new Point(10, 35 * i + 20);

    btnShow[i].Click += new EventHandler(Button_Click);

    btnShow[i].Tag = i.ToString();

    this.Controls.Add(btnShow[i]);

    }

    }

    public void Button_Click(object sender, EventArgs eArgs)

    {

    string strTag = ((Button)sender).Tag.ToString();

    Form frmSample = new Form();

    Label Info = new Label();

    switch (strTag)

    {

    case "0":

    Button btnClose = new Button();

    btnClose.Text = "Close";

    btnClose.Location = new Point((frmSample.Width - btnClose.Width) / 2, (frmSample.Height - btnClose.Height) / 2);

    btnClose.Click += new EventHandler(Close_Window);

    frmSample.ControlBox = false;

    frmSample.MaximizeBox = false;

    frmSample.MinimizeBox = false;

    frmSample.FormBorderStyle = FormBorderStyle.None;

    frmSample.Controls.Add(btnClose);

    frmSample.Show();

    break;

    case "1":

    frmSample.AutoScroll = true;

    Button btnSample = new Button();

    btnSample.Text = "Extreme";

    btnSample.Location = new Point(frmSample.Width + 20, frmSample.Height + 20);

    frmSample.Controls.Add(btnSample);

    frmSample.Show();

    break;

    case "2":

    frmSample.MaximumSize = new Size(300, 300);

    frmSample.MinimumSize = new Size(300, 300);

    Info.AutoSize = true;

    Info.Text = "Try Maximizing/Resizing Window";

    frmSample.Controls.Add(Info);

    frmSample.Show();

    break;

    case "3":

    frmSample.Closing += new CancelEventHandler(Form_Closing);

    frmSample.Show();

    break;

    case "4":

    frmSample.ShowInTaskbar = false;

    Info.AutoSize = true;

    Info.Text = "Minimize the window and you won't find it in TaskBar";

    frmSample.Controls.Add(Info);

    frmSample.Show();

    break;

    }

    }

    public void Close_Window(object sender, EventArgs eArgs)

    {

    ((Form)((Button)sender).Parent).Close();

    }

    public void Form_Load(object sender, EventArgs eArgs)

    {

    MessageBox.Show("Loading Form.....");

    }

    public void Form_Closing(object sender, CancelEventArgs cArgs)

    {

    if (sender == this)

    MessageBox.Show("Form Closing Event....");

    if (sender != this)

    {

    cArgs.Cancel = true;

    }

    }

    public static void View()

    {

    Application.Run(new FormDemo());

    }

    }

    }

     

     

    Enjoy it Smile

     

    Regards,

    Saturday, September 1, 2007 10:12 AM
  • Refactor!

    As ahmedilyas said above, you just shouldn't have a dll doing anything with forms.  DLL's are libraries. You should probably refactor your code, and consider using a Process.Start from the DLL to start your form independent of the dll. 

    If you can live with making your .dll an .exe, you'll be on a much smoother road.

    Saturday, September 1, 2007 9:38 PM
  • Hi Ray,

    I'm not sure what you mainly concern.

    What you should know is that once the Application.Run is called it begins running a standard application message loop on the current thread, the winform application runs depends on that message loop.

    If you want to do some extra work behind, to generate a background thread is the right way, BackGroundWorker can be considered.

    If I'm on the wrong track of the question, forget it.

     

    Thanks

    Tuesday, September 4, 2007 7:27 AM

  • As ahmedilyas said above, you just shouldn't have a dll doing anything with forms.  DLL's are libraries. You should probably refactor your code, and consider using a Process.Start from the DLL to start your form independent of the dll. 

    If you can live with making your .dll an .exe, you'll be on a much smoother road.


    That's not true at all. It is easy to put forms inside libraries! And we do it all the time, with no problems whatsoever.

    I really don't understand where this idea comes from that you should not display a form from library code...

    Think about it: People put User Controls inside libraries all the time, along with all their resources and localizations. There isn't that much difference between doing that and putting a form into a library.

    To add a form to a class assembly, you simply do Project | Add New Item and then select Windows Form.

    However, if you want to show that form from a Console app, you will need to do something like the following (assume the form is called MyForm):



    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MyForm());

     


    Tuesday, September 4, 2007 8:51 AM
  • That may well be the case but it's not the right method/approach of doing this.

     

    Tuesday, September 4, 2007 10:41 AM
    Moderator
  • Can you explain *why* it is not the right approach? So far you've just said that it isn't, without actually giving any reason for making that statement!
    Tuesday, September 4, 2007 11:50 AM
  • To the OP:

    This is how you can display a form from a class library from within a Console app:
    1. Create a class library. Let's call the assembly "ClassLibraryWithForm".
      (Here I must point out that when you create a default class library, a reference to the System.Windows.Forms assembly is automatically added to the project because, yes, Microsoft are expecting you to be able to add some Forms stuff to the class library.)
    2. Add a form to the class library. Let's call it MyTestForm. Put a test button on the form and wire it up to a handler that just displays a message box.
    3. Compile the class library.
    4. Create a default Console App.
    5. To the console app, add a reference to System.Windows.Forms.
    6. Also add a reference to your class library created in step (1).
    7. Add to the top of  Program.CS:     using System.Windows.Forms;
    8. Change the Main() method to look like the following, then compile and run it. Press return when prompted to display the form. Click the test button and see the test message.


    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new ClassLibraryWithForm.TestForm());
    }

     


    NOTE: That doesn't show you how to communicate with the form at runtime; to do so, you'd need another thread to do the work and call methods in the form that you expose. I'll post another message in a few mins to show you how to do so.


    Tuesday, September 4, 2007 12:06 PM
  • Example Continued: How to change the form's data from the console app:

    1. Add to the form in the class library a TextBox. Call it 'testTextBox'.
    2. Add this code to the form:



    private delegate void UpdateTextBoxDelegate(string newText);

    public void UpdateTextBox(string newText)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), new object[]{newText});
        }
        else
        {
            testTextBox.Text = newText;
        }
    }

     


    3. Change the code in the console app as follows:



    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        ClassLibraryWithForm.TestForm testForm = new ClassLibraryWithForm.TestForm();

        System.Threading.Thread worker = new System.Threading.Thread(DoWork);
        worker.Start(testForm);

        Application.Run(testForm);
    }

    private static void DoWork(object formObject)
    {
        ClassLibraryWithForm.TestForm form = formObject as ClassLibraryWithForm.TestForm;

        for (int i=0; i<=30; ++i)
        {
            form.UpdateTextBox(i.ToString());
            System.Threading.Thread.Sleep(1000);
        }
    }

     


    4. Now when you run the program, the text in the form's textbox will count up to 30.

    Tuesday, September 4, 2007 12:24 PM
  • Final example: Putting the form into a separate thread in the console app (this is an alternative to the previous example):



    static void Main(string[] args)
    {
        Console.WriteLine("Press return to launch the form.");
        Console.ReadLine();

        ClassLibraryWithForm.TestForm testForm = new ClassLibraryWithForm.TestForm();

        System.Threading.Thread formShower = new System.Threading.Thread(ShowForm);
        formShower.Start(testForm);

        for (int i=0; i<30; ++i)
        {
            if (testForm.IsDisposed)
            {
                Console.WriteLine("Form disposed, exiting.");
                break;
            }

            Console.WriteLine(i.ToString());
            testForm.UpdateTextBox(i.ToString());
            System.Threading.Thread.Sleep(1000);
        }
    }

    private static void ShowForm(object formObject)
    {
        ClassLibraryWithForm.TestForm form = formObject as ClassLibraryWithForm.TestForm;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(form);
    }

     


    Tuesday, September 4, 2007 12:40 PM
  • In my VS instance,  "using System.Windows.Forms;"   is not available to console apps. 

     


    nagendra mishr

    Wednesday, March 29, 2017 2:34 PM