Search code examples
c#winformstray

How to make many forms working?


I have an application with many forms that user can run from tray. But when user runs 2 forms, just the last one will work, until he closes it. After the second form is closed, the first one is working again.

How to make many forms working all the time, like other programs in window (eg. many windows of the same web browser)?

Here is part of code which i found on the internet, and i am using it for showing and hidings forms.

        public MyApplicationContext()
    {

        MenuItem SmsMenuItem = new MenuItem("SMS", new EventHandler(ShowSms));
        MenuItem ExitMenuItem = new MenuItem("Wyjdź", new EventHandler(Exit));
        MenuItem HistoryMenuItem = new MenuItem("Historia", new EventHandler(ShowHistory));


        NotifyIcon notifyIcon = new NotifyIcon();
        notifyIcon.Icon = SMSapp.Properties.Resources.Icon1;
        notifyIcon.ContextMenu = new ContextMenu(new MenuItem[] { SmsMenuItem, HistoryMenuItem, ExitMenuItem });
        notifyIcon.Visible = true;
    }

    void ShowSms(object sender, EventArgs e)
            {
        if (Globals.globals.Set.DBConn)
        {
            UnitOfWork uow = new UnitOfWork();
            using (SmsForm sm = new SmsForm(uow))
            {
                if (sm.Visible)
                    sm.Focus();
                else
                    sm.ShowDialog();
            }
        }
        else
        {

            using (SmsForm sm = new SmsForm())
            {
                if (sm.Visible)
                    sm.Focus();
                else
                    sm.Show();
            }
        }
    }

    void ShowHistory(object sender, EventArgs e)
    {
        if (Globals.globals.Set.DBConn)
        {
            UnitOfWork uow = new UnitOfWork();
            using (HistoryForm sm = new HistoryForm(uow))
            {
                if (sm.Visible)
                    sm.Focus();
                else
                    sm.ShowDialog();
            }
        }
        else
        {
            using (HistoryForm sm = new HistoryForm())
            {
                if (sm.Visible)
                    sm.Focus();
                else
                    sm.ShowDialog();
            }
        }
    }

    void Exit(object sender, EventArgs e)
    {
        notifyIcon.Visible = false;
        Application.Exit();
    }

Solution

  • The Problem is you have to use Show() instead of ShowDialog() so that the parent form and other forms are also clickable.

    Also remove the using from the method, because the using disposes of the new form after the statements inside the using are executed, which makes the form disappear.

    void ShowSms(object sender, EventArgs e)
    {
       SmsForm sm = new SmsForm();                
       if (sm.Visible)
         sm.Focus();
       else
         sm.Show();
    }
    

    EDIT: Updated answer on new information

    You don't need using for creating the Form, since the using basically does this:

    try{
      SmsForm sm = new SmsForm(); 
      //some code
    }
    finally{
      sm.Dispose(); 
    } 
    

    I would make it like something this:

    void ShowSms(object sender, EventArgs e)
    {
      SmsForm sm; 
      if (Globals.globals.Set.DBConn)
      {
        UnitOfWork uow = new UnitOfWork();
        sm = new SmsForm(uow);                    
      }
      else
        sm = new SmsForm();
      if (sm.Visible)
        sm.Focus();
      else
        sm.Show();
    }
    

    Now if there is something in your UnitOfWork class that needs to be disposed, like opening a DB Connection or something than use the using in that class/method where you use Disposable object.