1

編集2

さて、以下の回答に関するアドバイスに基づいて、スレッドアプローチを排除し、プログラムは次のようになります: program.cs

 static void Main(){

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

FrmWWCShell FrmWWCShell = null;
var splash = new FrmSplash();
splash.SplashFormInitialized += delegate
                                {
                                    FrmWWCShell = new FrmWWCShell();
                                    splash.Close();
                                };
Application.Run(splash);
Application.Run(FrmWWCShell);

}

FrmSplash.csはのようになります。

public partial class FrmSplash : Form
{

    public FrmSplash()
    {
        InitializeComponent();
    }

    protected override void  OnLoad(EventArgs e)
    {
        splashTimer.Interval = 1;
        splashTimer.Tick +=
            delegate { if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty); };
        splashTimer.Enabled = true;
    }

    public event EventHandler SplashFormInitialized;
}

問題は、それが現在まったく機能していないことです。スプラッシュ画面が一瞬ポップアップし、マークの進行状況バーが初期化されず、何も見つめずに dll とメイン フォームが表示されるまで 10 秒待っている間に消えます....

今ひどく混乱している私を着色してください!


元の投稿 - >参照用

すべての dll がロードされ、フォームが「ペイント」されている間、別のスレッドで動作する App Loading スプラッシュ スクリーンを実装しました。それは期待どおりに機能します。奇妙なのは、Splash フォームが終了すると、他に何か開いている場合 (つまり Outlook )、メインの Form が背面に送信されることです。Program.cs でスレッドを開始し、

static class Program
{
    public static Thread splashThread;

    [STAThread]
    static void Main()
    {
        splashThread = new Thread(doSplash);
        splashThread.Start();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FrmWWCShell());
    }

    private static void doSplash()
    {
        var splashForm = new FrmSplash();
        splashForm.ShowDialog();
    }
}

そして、FrmSearch_Shown イベントが発生したら終了します。

private void FrmSearch_Shown(object sender, EventArgs e)
    {
        Program.splashThread.Abort();
        this.Show();
        this.BringToFront();
    }

ご覧のとおり、FrmSearch で Show() および/または BringToFront() を呼び出してみましたが、それでも後ろに「ジャンプ」します。

私は何が欠けていますか?
他に何を試すことができますか?
私はこれをひどく無知にしているので、これを引き起こしているのは私のプロセスですか?
早期退職を申請する必要がありますか?

洞察をありがとう!


編集1

Main Form の TopMost プロパティをTRUEに設定してみました。これにより、フォームが非表示になることはありませんが、ユーザーが他のアプリを見ることもできなくなります。ちょっとナルシストっぽい…

4

2 に答える 2

5

まず第一に、UI 作業がプライマリ アプリケーション スレッドで行われることが非常に重要です。バックグラウンド スレッドでスプラッシュ スクリーンを表示しても、重大なエラーが発生していないことに、私はちょっと驚きました。

これが私が使用したテクニックです:

「実際の」フォームではなく、スプラッシュ フォームで Application.Run を使用します。

スプラッシュ フォームで、初期化されたイベントを用意します。

public event EventHandler SplashFormInitialized

1 ミリ秒で起動し、そのイベントをトリガーするタイマーを作成します。

次に、アプリケーションの実行メソッドで実際のフォームをロードし、スプラッシュ フォームを閉じて、実際のフォームで Application.Run を実行します。

var realForm = null;

var splash = new SplashForm();
splash.SplashFormInitialized += delegate {
  // As long as you use a system.windows.forms.Timer in the splash form, this
  // handler will be called on the UI thread
  realForm = new FrmWWCShell();
  //do any other init
  splash.Close();
}
Application.Run(splash); //will block until the splash form is closed

Application.Run(realForm);

スプラッシュには次のものが含まれる場合があります。

overrides OnLoad(...)
{
   /* Using a timer will let the splash screen load and display itself before
      calling this handler
   */
   timer.Interval = 1;
   timer.Tick += delegate {
     if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty);
   };
   timer.Enabled = true; 
}
于 2009-05-15T16:58:38.333 に答える
0

ショーの直後に Application.DoEvents() を呼び出してみてください。

警告: DoEvents を頻繁に呼び出さないでください。ただし、これはその 1 つです。

編集: クライドは、私が気付いていないことに気付きました: あなたはこれをスレッド化しています。別のスレッドで UI を実行しないでください。スレッドを取り出し、Application.DoEvents() に残します。

于 2009-05-15T16:48:03.383 に答える