好的,在我的应用程序中,有时加载DataGridView可能需要一两分钟。我想要做的是在没有边框的表单中显示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() + ")";
}
答案 0 :(得分:9)
理想情况下,您将拥有两个线程:GUI线程和工作线程(可以是BackgroundWorker
)。在GUI线程中创建并显示窗口。处理BackgroundWorker
的{{1}}事件中的加载。加载完成后,您可以在DoWork
事件的加载窗口中调用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
。
答案 1 :(得分:1)
是的,BackgroundWorker正是出于这种目的。要添加的几件事:
答案 2 :(得分: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();