سؤال

أريد شاشة البداية تظهر أثناء التطبيق تحميل.لقد شكل مع علبة نظام التحكم المرتبطة به.أريد شاشة البداية إلى حين عرض هذا النموذج الأحمال ، والتي تأخذ قليلا من الوقت منذ الوصول إلى خدمة ويب API لملء بعض المنسدلة.أنا أيضا أريد أن أفعل بعض اختبار أساسي تبعيات قبل التحميل (التي هي خدمة ويب متاح ملف التكوين غير قابل للقراءة).حيث أن كل مرحلة من مراحل بدء التشغيل يذهب, أريد تحديث شاشة البداية مع التقدم.

لقد قرأت الكثير عن خيوط, ولكن أنا أفقد حيث يجب أن يكون هذا التحكم من ( main() الطريقة؟).أنا أيضا في عداد المفقودين كيف Application.Run() يعمل هذا حيث المواضيع لهذا يجب أن يكون خلق من ؟ الآن, إذا كان النموذج مع علبة النظام السيطرة هو "العيش" النموذج ، ينبغي أن البداية تأتي من هناك ؟ لن يتم تحميل حتى اكتمال النموذج على أية حال ؟

أنا لا أبحث عن رمز صدقة ، أكثر من خوارزمية/النهج حتى أتمكن من معرفة هذا مرة واحدة وإلى الأبد :)

هل كانت مفيدة؟

المحلول

هذا التطبيق ClickOnce أنني نشرت في الماضي ، Microsoft.VisualBasic مساحة للتعامل مع شاشة البداية خيوط.يمكنك الرجوع واستخدام Microsoft.VisualBasic الجمعية من C# في .NET 2.0 و هذا يوفر الكثير من الخدمات الرائعة.

  1. يكون النموذج الرئيسي ترث من Microsoft.VisualBasic.WindowsFormsApplicationBase
  2. تجاوز "OnCreateSplashScreen" طريقة مثل ذلك:

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

واضحة جدا ، ويبين الخاص بك SplashForm (التي تحتاج إلى خلق) أثناء تحميل يجري ، ثم يغلق تلقائيا بمجرد النموذج الرئيسي اكتمال التحميل.

هذا حقا يجعل الأمور بسيطة ، VisualBasic.WindowsFormsApplicationBase هو طبعا اختبارها من قبل Microsoft و لديه الكثير من الوظائف التي يمكن أن تجعل حياتك أسهل كثيرا في Winforms ، حتى في تطبيق 100% C#.

في نهاية اليوم هي كل IL ، bytecode على أي حال, فلماذا لا تستخدم ذلك ؟

نصائح أخرى

الحيلة هي أن إنشاء مؤشر ترابط منفصل المسؤولة عن شاشة عرض.
عند تشغيل التطبيق لك .صافي يخلق الترابط الرئيسي وكميات محددة (الرئيسية) شكل.إخفاء العمل الشاق يمكنك إخفاء النموذج الرئيسي التحميل حتى يتم.

على افتراض أن Form1 - هو النموذج الرئيسي و SplashForm هو أعلى مستوى ، 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 لكن على ويندوز 2003 Terminal Server الرئيسي استمارة الطلب سوف تظهر (بعد شاشة البداية) في الخلفية ، فإن شريط المهام سوف وميض.وجلب النافذة الأمامية/التركيز في مدونة كل الديدان يمكنك جوجل/لذلك.

هذا هو السؤال القديم ، ولكن ظللت القادمة عبر هذا عندما تحاول أن تجد خيوط شاشة البداية حل WPF التي يمكن أن تشمل الرسوم المتحركة.

هنا هو ما كنت في نهاية المطاف تجميعها معا:

التطبيق.XAML:

<Application Startup="ApplicationStart" …

التطبيق.XAML.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(); في الإجابة التي تقدمها أكو.

نقلا عن MSDN:

تفعيل شكل يجلب أمام إذا كان هذا هو النشط التطبيق, أو ومضات من النافذة التعليق إذا كان هذا ليس هو النشط التطبيق.شكل يجب أن تكون مرئية لهذا الأسلوب أن يكون لها أي تأثير.

إذا كنت لا تفعيل النموذج الرئيسي ، فإنه قد يتم عرض خلف أي النوافذ المفتوحة ، مما يجعلها تبدو سخيفة بعض الشيء.

أعتقد أن استخدام بعض الأساليب مثل أكو أو الرجل هو الطريق للذهاب ، ولكن اثنين من الأمور التي تأخذ بعيدا عن أمثلة محددة:

  1. الفرضية الأساسية أن تظهر لطخة في موضوع مستقل في أقرب وقت ممكن.هكذا كنت العجاف ، على غرار ما أكو المصور ، حيث أنها الطريقة الأكثر دراية.لم أكن على علم VB وظيفة الرجل المذكور.و حتى ظننت انه VB مكتبة, هو الحق-كل شيء إل في نهاية المطاف.لذا حتى لو كان يشعر القذرة انها ليست كلها سيئة!:) أعتقد أنك سوف تريد أن تتأكد من أن إما VB يوفر موضوع مستقل في هذا تجاوز أو إنشاء واحدة بنفسك -- بالتأكيد البحث هذا.

  2. على افتراض انك إنشاء مؤشر ترابط آخر لعرض هذه البداية ، سوف تحتاج إلى أن يكون حذرا من الصليب موضوع واجهة المستخدم التحديثات.أحمل هذا الأمر لأنك ذكرت تحديث التقدم.الأساس أن تكون آمنة, أنت بحاجة إلى استدعاء وظيفة التحديث (إنشاء) في البداية شكل باستخدام مندوب.يمكنك تمرير ذلك مندوب الاحتجاج الدالة على شاشة البداية شكل الكائن.في الواقع إذا كنت استدعاء البداية النموذج مباشرة إلى التقدم تحديث/عناصر واجهة المستخدم على ذلك ، سوف تحصل على استثناء شريطة أن كنت تعمل على .Net 2.0 CLR.وكقاعدة عامة من الإبهام ، أي عنصر واجهة المستخدم على شكل يجب أن يكون تحديث بواسطة الخيط الذي قام بإنشائه -- وهذا ما شكل.الاحتجاج يؤمن.

وأخيرا ، من المرجح أن تختار لإنشاء البداية (إذا لم تكن تستخدم VB الزائد) في الأسلوب الرئيسي من التعليمات البرمجية الخاصة بك.بالنسبة لي هذا هو أفضل من وجود النموذج الرئيسي أداء إنشاء الكائن و أن يكون ذلك بإحكام إلى ذلك.إذا كنت تأخذ هذا النهج ، أود أن اقترح إنشاء واجهة بسيطة التي شاشة البداية تنفذ شيئا من هذا القبيل IStartupProgressListener-الذي يتلقى بدء التقدم التحديثات من خلال وظيفة عضو.هذا سوف يسمح لك بسهولة مبادلة في/خارج إما فئة حسب الحاجة و بشكل جيد على فصل القانون.البداية شكل يمكن أيضا أن تعرف متى تغلق نفسها إذا كنت تخطر عند بدء كاملة.

واحد طريقة بسيطة هو استخدام شيء من هذا القبيل كما main():

<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

عندما .NET CLR يبدأ التطبيق الخاص بك ، فإنه يخلق 'الرئيسية' الخيط يبدأ المنفذة الرئيسية الخاصة بك() على هذا الموضوع.التطبيق.تشغيل(myMainForm) في نهاية أمرين:

  1. يبدأ ويندوز 'رسالة مضخة', استخدام الخيط الذي تم المنفذة الرئيسية() مثل واجهة المستخدم الرسومية الموضوع.
  2. يعين الخاص بك 'النموذج الرئيسي' كما 'اغلاق شكل' التطبيق.إذا كان المستخدم يغلق هذا النموذج ، ثم التطبيق.تشغيل() ينتهي و يعود التحكم الرئيسي الخاص بك () ، حيث يمكنك أن تفعل أي اغلاق تريد.

ليست هناك حاجة إلى تفرخ الموضوع أن تأخذ الرعاية من البداية نافذة في الواقع هذا هو فكرة سيئة لأنه عندها سيكون لديك لاستخدام مؤشر الترابط-الآمن تقنيات تحديث البداية محتويات الرئيسية().

إذا كنت بحاجة إلى المواضيع الأخرى أن تفعل العمليات الخلفية في التطبيق الخاص بك ، يمكنك تفرخ من الرئيسية().فقط تذكر أن تعيين الموضوع.IsBackground إلى True ، بحيث أنها سوف تموت عندما الرئيسية / واجهة المستخدم الرسومية موضوع إنهاء.وإلا سيكون لديك لترتيب إنهاء جميع المواضيع الأخرى نفسك, أو أنها سوف تبقى التطبيق الخاص بك على قيد الحياة (ولكن مع عدم وجود واجهة المستخدم الرسومية) عندما الخيط الرئيسي إنهاء.

لقد نشرت مقالا على شاشة البداية شريط البحث في التطبيق في codeproject.وهي مؤشرات قد تكون من اهتمامك

آخر شاشة البداية في C#

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

حصلت على هذا من الإنترنت في مكان ما ولكن لا يمكن أن يبدو للعثور عليه مرة أخرى.بسيطة ولكن فعالة.

أنا أحب أكو الإجابة على الكثير ، ولكن التعليمات البرمجية لـ C# 3.0 وما فوق لأنه يستخدم وظيفة لامدا.بالنسبة للأشخاص الذين يحتاجون إلى استخدام التعليمات البرمجية في C# 2.0, هنا هو رمز باستخدام مجهول مندوب بدلا من وظيفة امدا.كنت في حاجة الى أعلى winform يسمى formSplash مع FormBorderStyle = 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 هنا ليست ضرورية.

اسمحوا الخاص بك الأعمال المنطق توليد الحدث كلما كنت ترغب في تحديث شاشة البداية.

ثم اسمحوا الخاص بك تحديث شكل شاشة البداية وبالتالي في طريقة التوصيل eventhandler.

التفريق التحديثات يمكنك إما النار الأحداث المختلفة أو تقديم بيانات في فئة موروثة من EventArgs.

بهذه الطريقة يمكنك الحصول على لطيفة تغيير شاشة البداية دون أي خاصية تعدد الصداع.

في الواقع مع هذا يمكنك حتى الدعم ، على سبيل المثال ، 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