如何使一个应用程序拥有表单但不是表单?

5
我希望我的C# .NET应用程序有一个表单但不是一个表单。
当我通常启动Windows窗体应用程序时,它就像表单是其后续所有内容的主人:
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

相反,我想启动我的程序,它可以显示一个表单,但本身不是表单。换句话说,我不希望应用程序的主控制器是表单,而是一个非可视逻辑容器,具有显示表单的功能,但本身不是表单。

我不确定我是否清楚地提出了问题,但我想听听大家的想法。


表单的显示是由什么触发的? - Conrad Frix
6个回答

7
你可以使用Application.Run()来启动一个消息循环。但你需要做一些事情来监听输入,比如系统托盘等。

1
这可能很明显,但我想指出的是,如果没有主窗体,那么应用程序将需要一些逻辑来决定何时调用Application.Exit()。 - Dr. Wily's Apprentice

5
您可以使用ApplicationContext。这将为您提供必要的消息循环,以保持窗体处于活动状态,一旦您决定创建一个窗体。请将您的Program类设置为类似以下内容:
static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        AppContext = new ApplicationContext();
        Application.Run(AppContext);
    }
    public static void Quit() {
        AppContext.ExitThread();
    }
    public static ApplicationContext AppContext;
}

请注意,当您关闭最后一个窗口时,该应用程序不会自动关闭。需要显式调用ExitThread函数来关闭。


2
正如Mark_Gravell所指出的,Application.Run()会一直阻塞直到Form1关闭。您可以在单独的线程上打开您的表单,但该线程将被基本消耗掉。当您想要退出exe时,您必须手动终止每个线程。请参见以下代码。(它不会创建控制台窗口。我通过创建默认的WinForms应用程序并更改Program类获得了这个代码)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    static class Program
    {

        static List<Thread> threads = new List<Thread>();
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            for (int i = 0; i < 10; i++)
            {
                StartThread();
                System.Threading.Thread.Sleep(500);
            }
            //kill each thread so the app will exit, otherwise, the app won't close
            //until all forms are manually closed...
            threads.ForEach(t => t.Abort());
        }

        static void StartThread()
        {
            Thread t = new Thread(ShowForm);
            threads.Add(t);
            t.Start();
        }

        static void ShowForm()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

2

通常会创建一个单独的引导程序组件,您可以将主窗体的显示移动到该组件中:

using System;
using System.Windows.Forms;

namespace Example
{
    internal static class Program
    {
        [STAThread]
        private static void Main()
        {
            new Bootstrapper().Run();
        }
    }

    public class Bootstrapper
    {
        public void Run()
        {
            // [Application initialization here]
            ShowView();
        }

        private static void ShowView()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

1

将应用程序创建为控制台应用程序,需要窗体时按照Marc的建议调用Application.Run。


除非是控制台应用程序,否则将强制创建控制台窗口。这可能不是Adam想要的。 - Steven Sudit

0

您也可以创建自己的ApplicationContext

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(AppController.Instance);
}

在 AppController.cs 中

namespace MyApplication
{
    public class AppController
    {
         static AppController _AppController;

         public LoginWIndow LoginWIndow;

         //Constructor
         public void AppController()
         {
             //Do what you will here, Start login form, bind events, w.e :)

             if(true) //Your check
             {
                 ShowLoginWindow();
             }
         }

         public void ShowLoginWindow()
         {
             LoginWIndow = new LoginWIndow();
             LoginWIndow.ClosedForm += new FormClosedEventHander(ExitApplication);
             LoginWIndow.Show();
         }

         public void ExitApplication(Object Sender, FormClosedEventArgs Args) 
         {
            //Some shutdown login Logic, then
            Application.Exit();
         }

         static AppController Instance
         {
            get
            {
                 if(_AppController == null)
                 {
                     _AppController = new AppController();
                 }
                 return _AppController;
            }
         }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接