Reputation: 1117
I've been searching StackOverflow and google for a while now for an answer to this and none of the answers seem to answer the question..
I've got a popup. All I want it to do is display "Please wait...", do some code, go away. No fun stuff, just simple.
Here is the xaml:
<Canvas Margin="0,0,0,0">
<Popup Name="dialogPopUp" StaysOpen="True" Placement="Center" Width="450">
<Border>
<Border.Background>
<LinearGradientBrush>
<GradientStop Color="AliceBlue" Offset="1"></GradientStop>
<GradientStop Color="LightBlue" Offset="0"></GradientStop>
</LinearGradientBrush>
</Border.Background>
<StackPanel Margin="5" Background="White">
<TextBlock FontFamily="Segoe UI" FontSize="16" Margin="10" TextWrapping="Wrap">Please wait for confirmation...
</TextBlock>
</StackPanel>
</Border>
</Popup>
... Rest of window xaml
My code:
dialogPopUp.IsOpen = true;
_Manager.DoWork();
dialogPopUp.IsOpen = false;
MessageBox.Show(_Manager.Report(), "Report");
So here's where it's weird. If I place the dialog.Popup.IsOpen = false; AFTER the MessageBox, (just to test to see that DoWork isn't instantaneous - though I know it's not) the popup is open when the MessageBox opens. Not before DoWork.
It refuses to open before DoWork. If I remove DoWork and put a Thread.Sleep(2000), same issue. The popup doesn't become visible until AFTER the sleep, even though the statement was before.
If I remove everything and just do a long while loop, nothing. The popup refuses to open until after the loop.
Any ideas?
Edit: To add, after some debugging, it doesn't become visible until the function exits (when I have MessageBox.Show removed).
IE:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
...
}
// popup opens here
With MessageBox:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
MessageBox.BlahBlahBlah // Popup opens here
...
}
Answer Edit: Theodosius Von Richthofen answered my question. Added BackgroundWorker:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
...
DoWorkClicked()
{
dialogPopUp.IsOpen = true;
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork (object sender, DoWorkEventArgs e)
{
this.DoWork();
backgroundWorker.ReportProgress(100)
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEvenetArgs e)
{
dialogPopUp.IsOpen = false;
}
Upvotes: 0
Views: 1617
Reputation: 2469
I believe you will need to DoWork with a BackgroundWorker or similar (newer versions of .NET have some new options Async/await etc), this is probably all on the UI thread. This would let the UI update BEFORE the work is done, effectively you are showing then not not showing it, and it doesn't update until after all that is done. What .NET Framework are you using? Here's an example, see the accepted answer...
How to correctly implement a BackgroundWorker with ProgressBar updates?
WPF ProgressBar usage when using Async/Await
Super simple .NET 4.5 example:
private async void Button_Click(object sender, RoutedEventArgs e)
{
this.dialogPopUp.IsOpen = true;
await Task.Run(() => DoWork());
this.dialogPopUp.IsOpen = false;
}
private void DoWork()
{
Thread.Sleep(5000);
}
Upvotes: 1