2010-09-21 3 views
1

Хорошо, в моем приложении есть моменты, когда загрузка DataGridView может занять минуту или две. То, что я хочу сделать, это показать GIF в форме без рамки, пока не достигнет конца функции загрузки. Однако, если я это сделаю:Как создать окно загрузки?

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

... он никогда не рисует его на экране, и я не вижу его. Если я показываю ShowDialog(), он показывает окно, но никогда не проходит мимо этой строки кода. У меня такое чувство, потому что это не фоновой работник или потому, что фокус возвращается к родительскому из-за обработки ... Я не знаю.

Моя форма - пустая форма, добавлена ​​картинка, добавлена ​​gif в окно с картинкой и выполнена FormBorderStyle = none. Любая помощь приветствуется.

Update: Текущий (нерабочий) Код

 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() + ")"; 
     } 
+0

Только, чтобы помочь с вашими поисками: Самый распространенный термин, который я слышал для них, - «Всплеск экрана». –

+0

lol. Да, я тоже искал это, но не получил много. Я все еще смотрю. Благодарю. – XstreamINsanity

ответ

9

В идеале вы должны иметь две темы: графический интерфейс поток и рабочий поток (который может быть BackgroundWorker). Создайте и покажите окно в потоке графического интерфейса. Обращайтесь с нагрузкой в ​​поле 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 собственности, которая должна быть установлена ​​на true. Вы также можете попробовать позвонить BringToFront() в окно загрузки после того, как вы создали и показали его.

+0

Вот что я думал. Дайте мне несколько, чтобы реализовать это. Благодарю. – XstreamINsanity

+0

Хорошо, у меня проблема. Я собираюсь поставить свой код там как Обновление. Я поставил точку останова в начале функции DoWork, которую я сделал в другом фоновом потоке, который я использовал, и он не попал в него. Если бы вы могли взглянуть, спасибо. – XstreamINsanity

+0

Хорошо, проблема заключается в том, что материал, который я использую для определения того, что отображается в DataGridView, нуждается в доступе к некоторым элементам управления, и для этого я получаю исключение для перекрестных потоков.Должен ли я сделать форму с GIF фоновым работником? – XstreamINsanity

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(); 
1

Да, BackgroundWorker предназначен именно для этого типа целей. Пара вещей, которые нужно добавить:

  1. Не взаимодействуйте с пользовательским интерфейсом в событии worker_DoWork, поскольку он работает в фоновом потоке. Установите e.Result, когда вы закончите, что вы можете проверить из события RunWorkerCompleted, или используйте переменную уровня формы.
  2. Пусть любые исключения проваливаются в событие worker_DoWork, и вы увидите их в событии worker_RunWorkerCompleted в e.Error.
  3. Если вам нужна возможность отменить свою нагрузку, установите employee.WorkerSupportsCancellation и проверьте e.Cancel во время вашего DoWork-события, тогда вы можете проверить e.Cancelled в вашем событии RunWorkerCompleted.
  4. Вы должны позвонить .Dispose() на BackgroundWorker по окончании.
Смежные вопросы