Reputation: 37
In my main window, I have a button that generates a report. But the report takes about 15 seconds to build, so I simply want to put up a small dialog that asks the user to "Please wait". It then just goes away when the report window is activated. The below works except that the "Please wait" dialog only produces the shell of the window, no content. Here is the code:
WD_PleaseWaitDialog _pWait = null;
private void ReportButton_Click( object sender, RoutedEventArgs e )
{
_pWait = new WD_PleaseWaitDialog();
_pWait.Show();
ReportWindow reportWindow = new ReportWindow(); // takes 15 seconds to execute
reportWindow.Activated += closePleaseWaitWindow;
reportWindow.Show();
}
private void closePleaseWaitWindow( object sender, System.EventArgs e )
{
_pWait.Close();
}
Upvotes: 0
Views: 1277
Reputation: 37
Thank you all for your answers. This is a great site and has provided me with lots of good info. This is what works, but it does not seem as elegant as I would like it to be:
private void ReportButton_Click( object sender, RoutedEventArgs e )
{
reportWindow = new BackUp.ReportWindow();
StatusBarTextBox.Text = "Generating report for \"" + DestinationDirectoryTextBox.Text + "\"";
StartWork();
} // END ReportButton_Click
private void StartWork()
{
_pWait = new WD_PleaseWaitDialog();
_pWait.Show();
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += DoWork;
worker.RunWorkerCompleted += WorkerCompleted;
worker.RunWorkerAsync();
}
private void DoWork( object sender, DoWorkEventArgs e )
{
reportWindow.initializeReportWindow( _dailyList, _weeklyList, _monthlyList, _semiAnnualList );
}
private void WorkerCompleted( object sender, RunWorkerCompletedEventArgs e )
{
_pWait.Close();
reportWindow.Show();
}
With this approach, I had to move the ReportWindow initialization out of the constructor and move it to an accessor.
Upvotes: 1
Reputation: 10152
What's happening is that your WD_PleaseWaitDialog
gets instantiated and when you Show()
it, it goes into Loaded
state, but that's right before Rendered
lifetime state. This is when you are creating your ReportWindow
, which takes a while to process (15 seconds according to you). What's happening is that you're essentially blocking the main thread during that time, which prevents WD_PleaseWaitDialog
from completing its rendering phase of its lifetime cycle. By the time your ReportWindow
finishes its loading, both of them get rendered, but it's so quick that you may not see the content of the WD_PleaseWaitDialog
at all before it's closed.
There are a couple of things you can do...
You might try working with the ContentRendered
event of the WD_PleaseWaitDialog
in order to proceed with the rest of the code. But, that couples the two windows... and that's not something I personally prefer.
You may consider using different threads. Task
class can greatly help you in this. One way this may be done is to put lengthy operations in your ReportWindow
into a Task
:
Task.Run(() => { // lengthy operation here });
When you're done with the operation, you'll need to call back into the main thread to close your WD_PleaseWaitDialog
(since you can't handle UI operations in other threads):
Application.Current.Dispatcher.BeginInvoke(
Dispatcher.Normal, new Action(_pWait.Close));
I'm not going to provide you the whole code unless you get really stuck. Try to do it yourself, since I've given you plenty of information to get started. Hope that helps.
Upvotes: 0
Reputation: 27348
Use dispatcher.begininvoke to generate and show report
Dispatcher.BeginInvoke(new Action(()=>{ /* report window */ });
Upvotes: 0