1

私のアプリでは、DataGridView の読み込みに 1 ~ 2 分かかる場合があります。私がやりたいのは、読み込み関数の最後に到達するまで、境界線のない形式でGIFを表示することです。しかし、もしそうなら:

Views.Loading ldw = new Views.Loading();
ldw.Show();
...
ldw.Close();

...実際には画面に描画されず、表示されません。ShowDialog() を実行すると、ウィンドウが表示されますが、そのコード行を超えることはありません。バックグラウンドワーカーではないか、処理のためにフォーカスが親に戻されるためだと思います...わかりません。

私のフォームは空白のフォームで、画像ボックスを追加し、画像ボックスに gif を追加し、FormBorderStyle = none にしました。どんな助けでも大歓迎です。

更新: 現在の (動作していない) コード

        private void InitializeBackgroundWorker()
        {
            //Defines the DoWork Event Handler for _backgroundWorker.
            _bgWorkerReports.DoWork += new DoWorkEventHandler(bgWorkerReports_DoWork);
            //Defines the RunWorkCompleted Event Handler for _backgroundWorker.
            _bgWorkerReports.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkerReports_RunWorkerCompleted);
        }

        private void bgWorkerReports_DoWork(object sender, DoWorkEventArgs e)
        {
            ldw.Show();
            try
            {                   
                string strFilter = "";

                if (!_strSearchFilter.Equals(""))
                {
                    strFilter += strFilter.Equals("") ? " " + _strSearchFilter : "  and " + _strSearchFilter;
                }

                if (tvFigure.Nodes.Count > 0)
                {
                    if (_strFigureFilter == "ALL")
                    {
                        strFilter += " " + Constants.GetColumnName("Figure") + " LIKE '%%' ";
                    }
                    else if (!_strFigureFilter.Equals("") && !_strFigureFilter.Equals(tvFigure.TopNode.Name))
                    {
                        if (_strSearchFilter.Equals("") || !cbCurrentFigure.Checked)
                        {
                            strFilter += strFilter.Equals("") ? " " + Constants.GetColumnName("Figure") + "='" + _strFigureFilter + "'" : " and " + Constants.GetColumnName("Figure") + "='" + _strFigureFilter + "'";
                        }
                    }
                }

                if (!_strIndentureFilter.Equals(""))
                {
                    strFilter += strFilter.Equals("") ? " " + _strIndentureFilter : "  and " + _strIndentureFilter;
                }

                if (!_strReportFilter.Equals(""))
                {
                    strFilter += (!strFilter.Equals("") ? " and" : "") + " part_id in (" + _strReportFilter + ")";
                }

                if (strFilter.Length > 0)
                {
                    BindingSource bSource = new BindingSource();
                    bSource.DataSource = _dataController.PopulateDataGrid(_nViewMode, strFilter).Tables[0];

                    //Set DataSource to bindingSource for DataGridView.
                    if (_lstValidationResults.Count > 0)
                    {
                        dgvParts.DataSource = _lstValidationResults;
                        foreach (DataGridViewColumn dc in dgvParts.Columns)
                        {
                            dc.DataPropertyName = "ErrorMessage";
                            dc.Visible = true;
                            dc.SortMode = DataGridViewColumnSortMode.Programmatic;
                            dc.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        }
                        dgvParts.AutoResizeColumns();
                        return;
                    }
                    else if (!string.IsNullOrEmpty(_strFigureFilter))
                    {
                        dgvParts.DataSource = bSource;
                        dgvParts.Columns[0].Visible = false;
                        dgvParts.Columns["Description"].Resizable = DataGridViewTriState.False;
                        dgvParts.Columns["Description"].Width = 750;
                    }

                    // Automatically resize the visible rows.
                    foreach (DataGridViewColumn col in dgvParts.Columns)
                    {
                        col.SortMode = DataGridViewColumnSortMode.Automatic;
                        if (col.Name != "Description")
                        {
                            dgvParts.AutoResizeColumn(col.Index);
                        }
                    }
                    dgvParts.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;

                    // Hide the ToolTips for all the cells - redisplay if there is a report.
                    dgvParts.ShowCellToolTips = true;

                    // Set the dataGridView control's border.
                    dgvParts.BorderStyle = BorderStyle.Fixed3D;

                    // Get and set the ipb_number to the label.
                    string ipb_number = _dataController.IPBNumber;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void bgWorkerReports_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ldw.Close();
            this.Cursor = Cursors.Default; //Throws error (Cross-thread)

            FormatCells();
            BuildColumnsComboBox();

            int nTotalCount = 0;

            foreach (ListViewItem lvi in listView1.Items)
            {
                int nCount = _lstReportRecords.Where(rr => lvi.Text.Contains(rr.Description)).Count();
                nTotalCount += nCount;
                lvi.Text = (lvi.Text.Contains("(") ? lvi.Text.Substring(0, lvi.Text.IndexOf("(") + 1) : lvi.Text.Trim() + " (") + nCount.ToString() + ")";
            }

            rbAllReports.Text = (rbAllReports.Text.Contains("(") ? rbAllReports.Text.Substring(0, rbAllReports.Text.IndexOf("(") + 1) : rbAllReports.Text + " (") + nTotalCount.ToString() + ")";
            int nTaggedCount = _lstReportRecords.Where(rr => rr.Description.Contains("Tagged")).Count();
            rbTaggedRecords.Text = (rbTaggedRecords.Text.Contains("(") ? rbTaggedRecords.Text.Substring(0, rbTaggedRecords.Text.IndexOf("(") + 1) : rbTaggedRecords.Text + " (") + nTaggedCount.ToString() + ")";
        }
4

3 に答える 3

9

理想的には、GUI スレッドと作業スレッド ( BackgroundWorker. GUI スレッドでウィンドウを作成して表示します。BackgroundWorkerDoWorkイベントでロードを処理します。読み込みが完了したら、イベントClose()から読み込みウィンドウを呼び出して破棄できます。RunWorkerCompleted

LoadWindow loadWindow = new LoadWindow();
loadWindow.TopMost = true;  // make sure it doesn't get created behind other forms
loadWindow.Show();

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    // do your loading here
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // set DataGridView datasource here
    ...

    // close loading window
    loadWindow.Close();
}

TopMostウィンドウの表示に関する問題は、 に設定する必要があるプロパティに起因する可能性がありますtrueBringToFront()ロード ウィンドウを作成して表示した後で、ロード ウィンドウを呼び出してみることもできます。

于 2010-09-21T13:21:39.667 に答える
1

はい、BackgroundWorkerはまさにこのタイプの目的のためのものです。追加するいくつかのこと:

  1. バックグラウンドスレッドで実行されているため、worker_DoWorkイベントでUIを操作しないでください。終了したらe.Resultを設定します。これは、RunWorkerCompletedイベントから確認できます。または、フォームレベルの変数を使用します。
  2. 例外がworker_DoWorkイベントで発生すると、e.Errorのworker_RunWorkerCompletedイベントで例外が表示されます。
  3. ロードをキャンセルする機能が必要な場合は、worker.WorkerSupportsCancellationを設定し、DoWorkイベントでe.Cancelを確認してから、RunWorkerCompletedイベントでe.Cancelledを確認できます。
  4. 終了したら、BackgroundWorkerで.Dispose()を呼び出す必要があります。
于 2010-09-21T13:36:31.847 に答える
0

コードを実行して、別のスレッドでグリッドを埋める必要があります。何かのようなもの:

// Set the picturebox loading state, resize the form etc.
PictureBox.SetLoadingImage();

// Initialize a new thread
Thread t = new Thread(new ThreadStart(() =>
{
    // Fill the gridview here
    GridView1.DataSource = FillWithData();
    GridView1.DataBind();

    // When finished, reset the picturebox on it's own thread
    PictureBox.Invoke((MethodInvoker)(()=> PictureBox.ClearLoadingImage() ));
}));

// Run the thread.
t.Start();
于 2010-09-21T13:23:27.667 に答える