문제

내가 원하는 시작 화면을 보여주면서 응용 프로그램입니다.나는 형태와 시스템 트레이의 통제에 묶여 있습니다.고 싶은 splash 화면이 표시는 동안 이 양식 로드하는 데 걸리는 시간이 조금이기 때문 웹 서비스에 액세스 API 를 채우는 어떤 드롭다운에 있습니다.나는 또한 몇 가지 기본적인 테스트에 대한 의존성하기 전에 선적(는 웹서비스를 이용하실 수 있으며,구성 파일을 읽을 수 있습니다).로의 각 단계를 시작이 간다고 싶 업데이트를 시작으로 화면 진행 중입니다.

나는 많이 읽기에 실을 꿰는,그러나 나는 길을 잃지에 이어야에서 통제(이하 main() 방법?).나도 누락 방법 Application.Run() 작품이 어디에 쓰레드 이를 위해 만들어야 합니까?지금는 경우,형태와 시스템 트레이의 제어는"살아있는"양식을 해야하는 스플래시에서 오는가?지 않을 로드되지 않을 양식이 완료될 때까지요?

내가 찾는 게 아니에요한 코드물을 더 알고리즘의/에 접근할 수 있도록 이 한번에 모두:)

도움이 되었습니까?

해결책

론,ClickOnce 응용 프로그램을 배포,과거에 우리가 사용하는 Microsoft.VisualBasic 네임스페이스를 처리합 시작 화면이 스레딩.할 수 있습에 참조 및 사용 Microsoft.VisualBasic 어셈블리에서는 C#습니다.NET2.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 어쨌든,왜 그것을 사용하지?

다른 팁

트릭을 만드는 별도의 스레드에 대한 책임이 시작 화면을 보이고 있다.
을 실행할 때 응용 프로그램.순성 main 스레드 실 지정된(주)형태입니다.을 은폐하는 노력을 숨길 수 있습니다 주요 형태가 될 때까지 로딩이 완료됩니다.

가정 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 서버는 터미널,주요 응용 프로그램 형태로 표시(시작 화면 후)에서 배경,그리고 작업 표시줄 것이 깜박입니다.을 창경/포커스 코드에서는 완전히 다른 수 있는 벌레의할 수 있습글/그렇습니다.

이것은 오래된 질문이지만,나는 그것에 걸쳐를 찾으려고 할 때 시작 화면이 스레드 솔루션에 대한 WPF 는 포함될 수 있습니다.

여기에 내가 궁극적으로 함께 재현:

App.XAML:

<Application Startup="ApplicationStart" …

App.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(); 에 응답이 제공 aku.

인용 MSDN:

를 활성화하는 형태로 제공하는 앞면 이 활성 응용 프로그램이나 그것을 깜박의 창 캡션이 아닌 경우 활성 응용 프로그램.의 양식을 볼 수 있어야 합니다 이 방법은 어떤 효과가 있습니다.

활성화하지 않는다면 당신의 주요 형태로 표시될 수 있습니다 뒤에 다른 창을 열고,이 상품에 대한 리뷰가 없습니다.

나는 생각을 사용하여 어떤 메소드 aku 의 은 방법으로 이동,하지만 부부의 것을 빼앗아에서 특정 예:

  1. 기본 전제로 한 것을 표시하는 스플래시에 별도의 thread 가능한 한 빨리.는 방법을 내가 기댈 것과 유사하게 아쿠의 그림이므로,방법으로 난이 중요합니다.모르고 있었 VB 기능을 사람이 언급했다.그리고,심지어는 생각은 그것의 VB 라이브러리,그가 바로-그것의 모든 IL 습니다.그래서 경우에도,그것은 느낌 그것은 모두 나쁘지 않다!:)저는 생각할 것이 있는지 확인하려면 하나 VB 제공하는 별도의 스레드에 있는 재정의 또는 하나의 자신을 만들-확실히 연구니다.

  2. 가정을 만드는 또 다른 스레드를 표시하는 이 시작하면 조심해야의 십자가는 실 UI 업데이트됩니다.내가 가지고 이것 때문에 당신이 언급한 업데이트를 진행합니다.기본적으로 안전을 위해,당신을 호출해야 업데이트 기능이(만)에 스플래시 양식을 사용하여할 수 있습니다.당신이 통과되는 대리인 Invoke 기능에서 시작 화면의 양식 개체입니다.사실에 전화하는 경우 스플래시 양식에 직접 진행 상황 업데이트/UI 요소에 그것은,당신은 예외가 제공하는 실행하고 있습니다.Net2.0CLR.엄지 손가락의 규칙으로,어떤 UI 요소에 양식을 업데이트해야 합니다 스레드에서 만든 그것이-그게 무슨 형태입니다.호출을 확실히 합.

마지막으로,나는 가능성을 선택하여 만들기를 시작(를 사용하지 않는 경우 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

다.데이 시작 응용 프로그램 만듭니다,그리고'주'스레드와 실행을 시작하 main()에는 스레드가 있습니다.응용 프로그램.실행(myMainForm)끝에서는 다음 두 가지를 수행합니다.

  1. 시작 Windows'메시지 펌프를 사용하여,스레드는 실행하는 main()으로 GUI thread.
  2. 지정한 당신의'메인 형태로'양식을 종료한 응용 프로그램.는 경우 사용자가 닫을 형성하는 다음 응용 프로그램.Run()종료하고 당신의 주요()할 수있는 모든 종료를 원합니다.

할 필요가 없이 스폰 스레드의 돌을 시작 창고,사실 이것은 나쁜 생각하기 때문에,다음 사용하 thread-safe 기술을 업데이트 시작 내용에서 주요().

필요한 경우 다른 스레드가 백그라운드 작업에의 응용 프로그램,생성할 수 있습에서 그들을 main().그냥 기억을 설정하는 스레드가 있습니다.IsBackground True,그래서 그들은 죽을 때 주요/GUI 스레드가 종료됩니다.그렇지 않으면 당신은 것을 준비해야를 종료하는 모든 다른 스레드에 자신을,또는 그들이 살아 있는 응용 프로그램(지만 어떠한 GUI)가 스레드가 종료됩니다.

게시 기사에서 시작 화면이 법인에서의 응용 프로그램에서 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();
}

이에 인터넷에서 어딘가에 그를 찾을 수 없습니다.간단하지만 아직 효과적입니다.

나는 다음과 같 Aku 의 대답이 많이 있지만,코드는 C#3.0 와 이후 사용하여 람다 함수입니다.필요한 사람들을 위해 사용하는 코드에서는 C#2.0,여기에 코드를 사용하여 익명의 위임 대한 람다 함수입니다.당신이 필요 맨 위 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 여기는 필요하지 않습니다.

귀하의 비즈니스를 논리 이벤트를 생성하려 할 때마다 업데이트합니다.

다음의 형태를 업데이트 스플래시 화면에 따라서는 방법에 푹 eventhandler.

구분 업데이트할 수 있습 화재 다양한 이벤트 또는 데이터를 제공하는 클래스에서부터 상속된 후 호출.

이 방법은 있을 수 있는 좋은 변화하는 시작 화면 없이 멀티 스레딩 두통입니다.

실제로 이와 함께 당신을 지원할 수 있습니다,예를 들어,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