Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

c# - Single Instance Windows Forms Application with Minimize to Tray

I have a sample WinForm application named "Restoring.exe". While minimizing its window, it will move to system tray and will be hidden in the taskbar. If I click on the notification icon in system tray, the window will come to the front.

public void notifyicon_MouseClick(object sender, System.EventArgs e)
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
}

But my actual requirement is, while clicking the application 2nd time, need to restore the application from system tray.

For this, I tried the below code

Program.cs:

static void Main()
{
    if (IsServiceManagerAlreadyRunning())
    {
        Form1 form1 = new Form1();
        form1.Restore();
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Form1.cs:

public void Restore()
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
} 

My actual issue is, if the application is already running, the 'Restore' method is hitting and all the actions listed in that is running and the window is appearing into front. But after completed those actions, the window again goes to the system tray. Not sitting in front.

Could anyone please provide a solution for this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Making Single Instance

Add a reference to Microsoft.VisualBasic.dll to your project and add this class to your project:

using System;
using Microsoft.VisualBasic.ApplicationServices;
using System.Windows.Forms;

namespace Sample
{
    public class ApplicationController : WindowsFormsApplicationBase
    {
        private Form mainForm;
        public ApplicationController(Form form)
        {
            //We keep a reference to main form 
            //To run and also use it when we need to bring to front
            mainForm = form;
            this.IsSingleInstance = true;
            this.StartupNextInstance += this_StartupNextInstance;
        }

        void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
        {
            //Here we bring application to front
            e.BringToForeground = true;
            mainForm.ShowInTaskbar = true;
            mainForm.WindowState = FormWindowState.Minimized;
            mainForm.Show();
            mainForm.WindowState = FormWindowState.Normal;
        }

        protected override void OnCreateMainForm()
        {
            this.MainForm = mainForm;
        }
    }
}

Then in your Program.cs use that ApplicationController to run the program:

using System;
using System.Windows.Forms;

namespace Sample
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //create a controller and Pass an instance of your application main form
            var controller =  new Sample.ApplicationController(new YourMainForm());

            //Run application
            controller.Run(Environment.GetCommandLineArgs());
        }
    }
}

Now your application is Single Instance and when you click on your exe file, instead of running another instance, brings the existing instance to front.

Using NotifyIcon

Put a NotifyIcon on your main form and then to hide window when you click minimize button and to show windows when you click on notify icon and you can handle these events:

//When click on notify icon, we bring the form to front
private void notifyIcon_Click(object sender, EventArgs e)
{
    this.ShowInTaskbar = true;
    this.WindowState = FormWindowState.Minimized;
    this.Show();
    this.WindowState = FormWindowState.Normal;
}

//here we check if the user minimized window, we hide the form
private void ApplicationMainForm_Resize(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized)
    {
        this.ShowInTaskbar = false;
        this.Hide();
    }
}

//when the form is hidden, we show notify icon and when the form is visible we hide it
private void ApplicationMainForm_VisibleChanged(object sender, EventArgs e)
{
    this.notifyIcon1.Visible = !this.Visible;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...