跨线程交叉形式。显示带有进度条的闪屏

时间:2011-07-14 10:58:12

标签: c# splash-screen

我的解决方案:

所以我设法找到另一个教程http://www.codeproject.com/KB/dotnet/Yet_Another_Splash_Screen.aspx,源代码对我来说似乎更有意义。这是我现在使用的代码。 Main()保持不变。

Splash.cs

`

  

公共部分类Frm_Splash:表单       {           delegate void ProgressDelegate(int percent);           委托void SplashShowCloseDelegate();

    /// <summary>
    /// To ensure splash screen is closed using the API and not by keyboard or any other things
    /// </summary>
    bool CloseSplashScreenFlag = false;

    /// <summary>
    /// Base constructor
    /// </summary>
    /// 
    public Frm_Splash()
    {
        InitializeComponent();
        progress_Splash.Show();
        this.ClientSize = this.BackgroundImage.Size;
    }

    public void ShowSplashScreen()
    {
        if (InvokeRequired)
        {
            // We're not in the UI thread, so we need to call BeginInvoke
            BeginInvoke(new SplashShowCloseDelegate(ShowSplashScreen));
            return;
        }
        this.Show();
        Application.Run(this);
    }

    /// <summary>
    /// Closes the SplashScreen
    /// </summary>
    public void CloseSplashScreen()
    {
        if (InvokeRequired)
        {
            // We're not in the UI thread, so we need to call BeginInvoke
            BeginInvoke(new SplashShowCloseDelegate(CloseSplashScreen));
            return;
        }
        CloseSplashScreenFlag = true;
        this.Close();
    }

    /// <summary>
    /// Update text in default green color of success message
    /// </summary>
    /// <param name="Text">Message</param>
    public void Progress(int percent)
    {
        if (InvokeRequired)
        {
            // We're not in the UI thread, so we need to call BeginInvoke
            BeginInvoke(new ProgressDelegate(Progress), new object[] { percent });
            return;
        }
        // Must be on the UI thread if we've got this far
        progress_Splash.Value = percent;
        // Fade in the splash screen - looks pro. :D
       if (percent < 10)
            this.Opacity = this.Opacity + .15;
    }


    /// <summary>
    /// Prevents the closing of form other than by calling the CloseSplashScreen function
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SplashForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (CloseSplashScreenFlag == false)
            e.Cancel = true;
    }
 }`

Form1.cs的

public partial class Frm_Main : Form
{
    Frm_Splash frm_Splash = new Frm_Splash();

    public Frm_Main()
    {
        this.Hide();
        Thread splashthread = new Thread(new ThreadStart(frm_Splash.ShowSplashScreen));
        splashthread.IsBackground = true;
        splashthread.Start();
        InitializeComponent();
        CenterToScreen();
    }

    private void Frm_Main_Load(object sender, EventArgs e)
    {
        if (PassedAll() == true)
            FillMovieLB();
        if (FillMovieProgress == 100)
        {
            //Throw in this sleep so the user can see the progress bar reach all the way to the end.
            Thread.Sleep(1000);
            this.Show();
            frm_Splash.CloseSplashScreen();
            this.Activate();
        }
    }

原始问题

G'day all,

我对使用C#进行编程非常陌生,我遇到了http://www.codeproject.com/KB/cs/prettygoodsplashscreen.aspx教程的问题,并在我的应用程序中实现它。我发现有点难以理解问题所在。我知道有很多关于让这个启动画面工作的东西,但我无法理解它。

当我启动该程序时,会显示Frm_Main,您可以看到正在填充listbox,因为我已将其放入BackgroundWorker.DoWork(),然后我的{{1}工作完成后会显示。显然,它应该工作的方式是,frm_Splash将在frm_Splash的工作期间显示,进度条将显示加载的进度(这部分我还没有实现)

编辑:我可能不太清楚,但问题是:如何在工作完成时以及显示主表单之前显示我的启动画面?

谢谢大家。 :)

这是我的代码:

Frm_Main

2 个答案:

答案 0 :(得分:2)

在这里,有一些代码......适合我。

启动表格:

namespace Screens.Forms
{
    public partial class Splash : DevExpress.XtraEditors.XtraForm
    {
        public Splash()
        {
            InitializeComponent();
        }
        string RandomLoadingMessage()
        {
            string[] lines ={
                "Pripremam warp pogon",
                "Moj drugi ekran za učitavanje je brži, probaj njega",
                "Verzija programa koju imam u testiranju imala je smiješnije poruke"
            };
            return lines[new Random().Next(lines.Length)];
        }
        public void RandomizeText()
        {
            lblMessage.Text = RandomLoadingMessage();
        }
        private void Splash_Load(object sender, EventArgs e)
        {
            RandomizeText();
        }
        private static Splash _splash;
        private static bool _shouldClose;

        static void ThreadFunc()
        {
            _splash = new Splash();
            _splash.Show();
            while (!_shouldClose)
            {
                Application.DoEvents();
                Thread.Sleep(100);
                if (new Random().Next(1000) < 10)
                {
                    _splash.Invoke(new MethodInvoker(_splash.RandomizeText));
                }
            }
            for (int n = 0; n < 18; n++)
            {
                Application.DoEvents();
                Thread.Sleep(60);
            }
            if (_splash != null)
            {
                _splash.Close();
                _splash = null;
            }
        }
        static public void ShowSplash()
        {
            _shouldClose = false;
            Thread t = new Thread(ThreadFunc);
            t.Priority = ThreadPriority.Lowest;
            t.Start();
        }
        internal static void RemoveSplash()
        {
            _shouldClose = true;
        }
        internal static void ShowSplash(List<string> fromTwitterMessages)
        {
            ShowSplash();
        }
    }
}

用以下方式显示:

Splash.ShowSplash();

完成所需的工作,然后完成:

Splash.RemoveSplash();

答案 1 :(得分:0)

您需要更进一步回到应用程序的Main()功能。 一般来说,你可以这样做:

  • 如果您使用的是.NET 4
  • ,请创建ManualResetEvent或更好ManualResetEventSlim
  • 启动显示SplashScreen的新主题,使用Application.Run
  • 在你的SplashScreen中,你应该创建一个轮询创建的ManualResetEvent的时间 经常,这里也可以放置一个漂亮的动画
  • 如果设置了该事件,则应关闭表单
  • 回到你的Main()做你的事情,比如创建表格等。
  • 完成设置事件后,可以关闭SplashScreen
  • 为确保在您的SplashScreen关闭之前未显示MainForm,您可以使用其他活动