20

スプラッシュスクリーンにまだ問題があります。プロパティを使用したくありませんSC.TopMost=true

現在、私のアプリケーションシナリオは次のとおりです。

progeram.cs で:

[STAThread]
static void Main()
{
    new SplashScreen(_tempAL);// where _tempAL is an arrayList
    Application.Run(new Form1(_tempAL));
}

SplashScreen クラス:

public SplashScreen(ArrayList _Data)
{
    DisplaySplash()
} 
private void DisplaySplash()
{
    this.Show();
    this.TopMost = true;
    this.CenterToScreen();
    this.SetTopLevel(true);

    _allServerNarrators = new string[10];
    for (int i = 0; i < _allServerNarrators.Length; i++)
        _allServerNarrators[i] = null;

    GetFromServer();

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

}
private void GetFromServer()
{
    _serverNarrators = new ArrayList();
    string _file = "Suras.serverNar";

    if (!Directory.Exists("c:\\ASGAQuraan"))
        Directory.CreateDirectory("c:\\ASGAQuraan");

    while (counter < 4 && _serverFiles == null)
    {
        if (Download("c:\\ASGAQuraan", _ftpServerIP, _file))
        {
            StreamReader _strReader = new StreamReader
                         ("c:\\ASGAQuraan\\"+_file,System.Text.Encoding.Default);
            string _line = _strReader.ReadLine();
            string _word;

            while (true)
            {
                while (_line != null)
                {
                    _word = _line.Substring(0, _line.IndexOf("*"));
                    int _narId = Convert.ToInt32(_word);
                    _line = _line.Substring(2);
                    int k = 0;
                    _serverNarratorNode = new ArrayList();
                    while (true)
                    {
                        int ind = _line.IndexOf("*");
                        if (ind > 0 && ind < _line.Length)
                        {
                            string str = _line.Substring(0, (ind));
                            if (k == 0)
                            {
                                _allServerNarrators[_narId] = str;
                                _serverNarratorNode.Add(str);
                            }
                            else
                            {
                                _serverNarratorNode.Add(str);
                            }
                            _line = _line.Substring(ind + 1);
                            k++;
                        }
                        else
                        {
                            _line = null;
                            break;
                        }
                    }
                    _serverNarrators.Add(_serverNarratorNode);
                    _serverFiles = "added";
                }
                _line = _strReader.ReadLine();
                if (_line == null)
                {
                    break;
                }
            }
        }
        else
            counter++;
    }
}

私が欲しいのは、スレッドが終了するまで待機するスプラッシュ スクリーン クラスの何かです。

詳細については、私があなたに言う必要があることを教えてください。

4

5 に答える 5

83

同じ質問、同じ答え:

.NET フレームワークには、スプラッシュ スクリーンのサポートが組み込まれています。新しい WF プロジェクト (プロジェクト + 参照の追加) を開始し、Microsoft.VisualBasic を選択します。新しいフォームを追加し、それを frmSplash と呼びます。Project.cs を開き、次のようにします。

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace WindowsFormsApplication1 {
  static class Program {
    [STAThread]
    static void Main(string[] args) {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      new MyApp().Run(args);
    }
  }
  class MyApp : WindowsFormsApplicationBase {
    protected override void OnCreateSplashScreen() {
      this.SplashScreen = new frmSplash();
    }
    protected override void OnCreateMainForm() {
      // Do your time consuming stuff here...
      //...
      System.Threading.Thread.Sleep(3000);
      // Then create the main form, the splash screen will close automatically
      this.MainForm = new Form1();
    }
  }
}
于 2008-12-26T15:11:46.433 に答える
3

Application.Run() を呼び出す前に UI を作成することで、危険な領域に入りました。Application.Run は、基本的にプログラムのメッセージ ポンプです。アプリケーションのメッセージ ポンプを開始する前に UI を表示することで、通常の UI の操作を未熟な UI で事実上不可能にします。スプラッシュ スクリーンの場合、これは関係ないように見えるかもしれませんが、(たとえば) スプラッシュ スクリーンがクリックされた場合にスプラッシュ スクリーンを非表示にする要求がある場合や、BackgroundWorker を使用する場合は問題になります。

これらは、スプラッシュ スクリーンにメッセージ ポンプを作成する (Show() の代わりに ShowDialog() を呼び出してモーダルにする) ことで回避できますが、問題を処理することは実際にはそれほど難しくありません。

この場合、nobugzの回答を強くお勧めします。フレームワークは、必要なサポートを提供します。Microsoft.VisualBasic 名前空間の機能は、C# プログラマにとって常に発見しやすいわけではありませんが、このような場合には、時間を節約し、命を救うことができます。

幸運を!

于 2008-12-26T15:34:52.317 に答える
2

2 つのスレッドにまたがってフォローするのは少し混乱しますが、突き刺してこう言います...

ここであなたのデザインを完全には理解していませんが、問題が 2 番目のアプリケーションを起動したときにスプラッシュ スクリーン フォームが白くなることである場合は、スプラッシュ スクリーンが GetFromServer でそのすべてのコードを実行していることが原因である可能性が最も高いです。 (). 忙しすぎて塗り直す暇がない。

この問題を解決するには、BackGroundWorker コンポーネントを使用して GetFromServer メソッドを実行することをお勧めします。これにより、そのメソッドが別のスレッドで実行され、フォームのスレッドが自由に再描画できるようになります。

于 2008-12-25T15:50:06.937 に答える
1

問題の詳細を提供する必要があります。私は完全に間違っている可能性がありますが、暗闇の中でショットを撮るつもりです. 私が想像していることから、スプラッシュ画面を表示し、別のスレッドで処理を行い、終了したらスプラッシュ画面を消す必要があります。

これを行うには、GetFromServer()呼び出しをに移動する必要がありBackgroundWorkerます。次に、

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

コードをBackgroundWorker_RunWorkerCompletedイベント ハンドラに追加します。

を使用するにはBackgroundWorker:

1) 初期化BackGroundWorker

  BackgroundWorker myWorker = new BackgroundWorker();

2) イベント ハンドラーを追加する

  myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
  //put the work you want done in this one

  myWorker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
  //this gets fired when the work is finished

3) イベント ハンドラにコードを追加します。

4)myWorker.RunWorkerAsync()作業を開始するために呼び出します。

ArrayList別のメモとして、スプラッシュ スクリーンのコンストラクターに渡している で何もしていないようです。これは意図したものですか?

于 2008-12-25T15:50:24.893 に答える