我想要一个闪屏幕上显示时应用程序。我有一种形式有系统的盘控制系到它。我希望启动屏幕显示虽然这一形式载荷,它需要一点时间因为这是访问网服务API填充一下起伏。我也要做一些基本的测试为依赖在装货之前(即,网服务提供,配置文件的可读).为每个阶段的启动时,我想要更新的初始屏幕与进步。

我已经阅读了很多线程,但我迷失在其中这应该是控制从(在 main() 方法?).我也失踪如何 Application.Run() 工作的,是这里的线为此应建立从?现在,如果形式,与系统的盘控制是"生活"的形式,应该初始从那里来的?它不会不负载直到的形式是完成呢?

我不是在寻找一个代码讲义,更多的算法/办法,所以我可以推测这一次所有:)

有帮助吗?

解决方案

嗯,所应用程序,我已部署在过去,我们使用 Microsoft.VisualBasic 名字空间,以处理初始屏幕,穿线。你可以参考和使用 Microsoft.VisualBasic 大会从C#。网2.0的,它提供了一个很好的服务。

  1. 有的主要形式的继承 Microsoft.VisualBasic.WindowsFormsApplicationBase
  2. 复盖"OnCreateSplashScreen"的方法,像这样:

    protected override void OnCreateSplashScreen()
    {
        this.SplashScreen = new SplashForm();
        this.SplashScreen.TopMost = true;
    }
    

非常简单的,它显示了你的,并在窗体保(这需要创建),同时装货是怎么回事,然后关闭它自动的主要形式已经完成的负载。

这真的会让事情简单, VisualBasic.WindowsFormsApplicationBase 当然是经过良好测试的通过微软以及具有很大的功能,可以让你的生活变得更容易在它,甚至在应用程序是100%。

在一天结束,它是所有IL和 bytecode 无论如何,那么,为什么不用呢?

其他提示

关键是要创建独立的线负责初始屏幕显示。
当你把你的应用程序。净创建了主线程和载荷的规定(主要)的形式。来掩盖苦的工作你可以隐藏的主要形式,直到装载完成。

假设Form1-是你的主要形式,并在窗体保是顶级,borderles漂亮的飞溅形式:

private void Form1_Load(object sender, EventArgs e)
{
    Hide();
    bool done = false;
    ThreadPool.QueueUserWorkItem((x) =>
    {
        using (var splashForm = new SplashForm())
        {
            splashForm.Show();
            while (!done)
                Application.DoEvents();
            splashForm.Close();
        }
    });

    Thread.Sleep(3000); // Emulate hardwork
    done = true;
    Show();
}

后找谷歌和这样的解决方案,这是我最喜欢的:http://bytes.com/topic/c-sharp/answers/277446-winform-startup-splash-screen

FormSplash.cs:

public partial class FormSplash : Form
{
    private static Thread _splashThread;
    private static FormSplash _splashForm;

    public FormSplash() {
        InitializeComponent();
    }

    /// <summary>
    /// Show the Splash Screen (Loading...)
    /// </summary>
    public static void ShowSplash()
    {
        if (_splashThread == null)
        {
            // show the form in a new thread
            _splashThread = new Thread(new ThreadStart(DoShowSplash));
            _splashThread.IsBackground = true;
            _splashThread.Start();
        }
    }

    // called by the thread
    private static void DoShowSplash()
    {
        if (_splashForm == null)
            _splashForm = new FormSplash();

        // create a new message pump on this thread (started from ShowSplash)
        Application.Run(_splashForm);
    }

    /// <summary>
    /// Close the splash (Loading...) screen
    /// </summary>
    public static void CloseSplash()
    {
        // need to call on the thread that launched this splash
        if (_splashForm.InvokeRequired)
            _splashForm.Invoke(new MethodInvoker(CloseSplash));

        else
            Application.ExitThread();
    }
}

程序。cs:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // splash screen, which is terminated in FormMain
        FormSplash.ShowSplash();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        // this is probably where your heavy lifting is:
        Application.Run(new FormMain());
    }
}

FormMain.cs

    ...

    public FormMain()
    {
        InitializeComponent();            

        // bunch of database access, form loading, etc
        // this is where you could do the heavy lifting of "loading" the app
        PullDataFromDatabase();
        DoLoadingWork();            

        // ready to go, now close the splash
        FormSplash.CloseSplash();
    }

我有问题 Microsoft.VisualBasic 解决方案--工作上找到XP,但在Windows server2003终端服务器,主要应用程序的形式出现(后的初始屏幕)的背景和任务栏会闪烁。并带来一个窗口前景/重点放在代码是一个整体的其他可能的蠕虫你可以Google/SO。

这是一个老问题,但我一直碰到它时,试图找到一个螺纹飞溅的画面解决方案WPF可能包括动画。

这里是我的最终拼凑在一起:

应用程序。键

<Application Startup="ApplicationStart" …

应用程序。停靠。cs:

void ApplicationStart(object sender, StartupEventArgs e)
{
        var thread = new Thread(() =>
        {
            Dispatcher.CurrentDispatcher.BeginInvoke ((Action)(() => new MySplashForm().Show()));
            Dispatcher.Run();
        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();

        // call synchronous configuration process
        // and declare/get reference to "main form"

        thread.Abort();

        mainForm.Show();
        mainForm.Activate();
  }

我建议叫 Activate(); 之后直接去 Show(); 在回答提供aku.

引用MSDN:

激活的一种形式,它带来的 前如果是这样的活动 应用程序,或者它闪烁的窗口 字幕如果这不是活动 应用程序。形式必须是可见的 对于这种方法有任何效果。

如果你没激活的主要形式,它可以显示 背后 任何其它打开的窗口,使它看起来有点傻。

我认为使用一些方法像 aku的那家伙的 是的路要走,但是一对夫妇的事情要远离的具体实例:

  1. 基本的前提就是展现你的飞溅上一个单独的线尽快。这就是我想精益,类似于什么aku的说明,由于这是我最熟悉的。我不知道VB功能的人提及。而且,甚至认为它是一个 VB 库,他是正确的--这是所有的IL在结束。因此,即使感觉 肮脏的 这是不是所有的错!:)我想你会想要确保,无论是VB提供了一个独立的线程中,复盖或者是你自己创建一个-肯定的研究。

  2. 假设你在建立另外一个线程,以显示该飞溅,你要小心的交叉线UI更新。我带来这因为你提到的更新的进展。基本上,为了安全起见,你需要叫更新的功能(即创建)在启动形式使用的委托。你通过这一委托的 调用 功能上你的初始屏幕上的形象。事实上,如果你叫飞溅形式直接更新的进度/UI元素,你会得到一个异常提供运行。网2.0CLR。作为一个原则,任何用户界面上的元素的一种形式必须更新在线创建了它-那是什么形式。援引保证.

最后,我可能会选择建立该飞溅的(如果不使用VB载)在主要方法。对我来说,这是更好的比具有的主要形式进行创作的对象和如此紧密结合。如果你采取这种做法,我建议建立一个简单的接口,启动画面实现--什么喜欢IStartupProgressListener--其接收启动的进度更新经由一个部件的功能。这会让你很容易地交换出任何一类需要,并很好地分离的代码。溅形式还可以知道什么时候接近本身,如果您通知时开始是完整的。

一个简单的方法是使用这样的东西作为主():

<STAThread()> Public Shared Sub Main()

    splash = New frmSplash
    splash.Show()

    ' Your startup code goes here...

    UpdateSplashAndLogMessage("Startup part 1 done...")

    ' ... and more as needed...

    splash.Hide()
    Application.Run(myMainForm)
End Sub

时。净CLR开始你的应用程序,它创建了一个'主要'线,并开始执行你的主要()上线。该应用程序。运行(myMainForm)结束时做两件事:

  1. 开始的Windows的消息泵,使用螺纹,已经执行主()作为GUI线。
  2. 指定的'主要形式'作为'停形式的应用程序。如果用户的关闭形式,则该应用程序。运行()终止和控制回到你主(),在这里你可以做任何关机你想要的。

没有必要产生一线照顾的飞溅的窗口,而事实上这是一个糟糕的想法,因为那时你会有用的线安全的技术来更新启动内容的自主().

如果你需要其他的线做背景的操作应用程序,则可能产生他们自主().只记得设置线。IsBackground到真实的,所以,他们将死时的主/GUI线的终止。否则你将不得不安排终止所有其他线自己,否则他们会让你的应用程序还活着(但没有GUI)当主线的终止。

我发布了一条关于初始屏幕,以纳入应用程序演示.它是多线程和可能是你感兴趣的

又一个初始屏幕C#

private void MainForm_Load(object sender, EventArgs e)
{
     FormSplash splash = new FormSplash();
     splash.Show();
     splash.Update();
     System.Threading.Thread.Sleep(3000);
     splash.Hide();
}

我从互联网上的某个地方,但似乎不能再次找到它。简单但有效的。

我喜欢Aku的回答很多,但是代码是为C#3.0,因为它使用一种氧功能。人们需要使用代码在C#2.0,这里的代码使用匿名的委托,而不是lambda功能。你需要一个最上面的winform叫 formSplashFormBorderStyle = None.的 TopMost = True 参数的形式是重要的,因为启动画面可能看上去像出现然后迅速消失,如果它不是最顶层。我还选择 StartPosition=CenterScreen 因此它看起来像什么一个专业的应用程序将与初始屏幕。如果你想要一个更酷的效果,可以使用 TrasparencyKey 酒店做一个不规则形状的初始屏幕。

private void formMain_Load(object sender, EventArgs e)
  {

     Hide();
     bool done = false;
     ThreadPool.QueueUserWorkItem(delegate
     {
       using (formSplash splashForm = new formSplash())
       {
           splashForm.Show();
           while (!done)
              Application.DoEvents();
           splashForm.Close();
       }
     }, null);

     Thread.Sleep(2000);
     done = true;
     Show();
  }

我不同意的其他答复建议 WindowsFormsApplicationBase.以我的经验,它可以减缓你的应用程序。准确地说,虽然它运行形式的构造平行动屏幕推迟您的表格所示的事件。

考虑一个程序(不splashs屏幕)与构造,需要1次和事件的处理程序在所示,带2秒钟。这个程序是使用经过3秒钟。

但是假设你安装了一个闪屏使用 WindowsFormsApplicationBase.你可能会认为 MinimumSplashScreenDisplayTime 3秒钟的是明智和不会减缓你的应用程序。但是,试一试,你的应用程序现在将需要5秒钟来载荷。


class App : WindowsFormsApplicationBase
{
    protected override void OnCreateSplashScreen()
    {
        this.MinimumSplashScreenDisplayTime = 3000; // milliseconds
        this.SplashScreen = new Splash();
    }

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

public Form1()
{
    InitializeComponent();
    Shown += Form1_Shown;
    Thread.Sleep(TimeSpan.FromSeconds(1));
}

void Form1_Shown(object sender, EventArgs e)
{
    Thread.Sleep(TimeSpan.FromSeconds(2));
    Program.watch.Stop();
    this.textBox1.Text = Program.watch.ElapsedMilliseconds.ToString();
}

结论:不要用 WindowsFormsApplicationBase 如果你程序有一个处理程序上的Slown事件。你可以写更好的代码运行的飞行于两个构造和所示的事件。

实际上mutlithreading在这里是不是有必要的。

让你的商务逻辑产生的一个事件只要你想要的更新启动画面。

然后让你的形式更新启动屏幕因此在方法上钩来处理.

区分的更新可以火不同的活动或提供的数据在一类继承定引.

这种方式可以有很好的改变初始屏幕没有任何多头痛的问题。

实际上这个,你甚至可以支持,例如,gif上的图像一个喷溅形式。为了它的工作,呼应用程序。DoEvents()在您的处理程序:

private void SomethingChanged(object sender, MyEventArgs e)
{
    formSplash.Update(e);
    Application.DoEvents(); //this will update any animation
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top