基于 C# Web 的 WPF - Popup IsOpen 不工作
C# Web based WPF - Popup IsOpen not working
我已经在 Whosebug 和 google 上搜索了一段时间来寻找这个问题的答案,none 的答案似乎回答了这个问题..
我有一个弹出窗口。我想让它做的只是显示 "Please wait...",做一些代码,走开。没什么好玩的,就是简单。
这是 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
我的代码:
dialogPopUp.IsOpen = true;
_Manager.DoWork();
dialogPopUp.IsOpen = false;
MessageBox.Show(_Manager.Report(), "Report");
这就是奇怪的地方。如果我放置 dialog.Popup.IsOpen = false;在 MessageBox 之后,(只是为了测试 DoWork 不是瞬时的——虽然我知道它不是)当 MessageBox 打开时弹出窗口是打开的。不是在 DoWork 之前。
它拒绝在 DoWork 之前打开。如果我删除 DoWork 并放置 Thread.Sleep(2000),同样的问题。弹出窗口在睡眠之后才会变得可见,即使声明是在之前。
如果我删除所有内容并只执行一个很长的 while 循环,则什么也没有。弹出窗口拒绝打开,直到循环结束。
有什么想法吗?
编辑:要添加,经过一些调试后,直到函数退出时它才可见(当我删除 MessageBox.Show 时)。
IE:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
...
}
// popup opens here
使用消息框:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
MessageBox.BlahBlahBlah // Popup opens here
...
}
答案编辑:Theodosius Von Richthofen 回答了我的问题。添加了 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;
}
我相信您需要使用 BackgroundWorker 或类似工具(较新版本的 .NET 有一些新选项 Async/await 等),这可能都在 UI 线程上。这将使 UI 在工作完成之前更新,有效地显示然后不显示它,并且在完成所有操作之前它不会更新。您使用的是什么 .NET 框架?这是一个示例,请参阅已接受的答案...
How to correctly implement a BackgroundWorker with ProgressBar updates?
WPF ProgressBar usage when using Async/Await
超级简单的 .NET 4.5 示例:
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);
}
我已经在 Whosebug 和 google 上搜索了一段时间来寻找这个问题的答案,none 的答案似乎回答了这个问题..
我有一个弹出窗口。我想让它做的只是显示 "Please wait...",做一些代码,走开。没什么好玩的,就是简单。
这是 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
我的代码:
dialogPopUp.IsOpen = true;
_Manager.DoWork();
dialogPopUp.IsOpen = false;
MessageBox.Show(_Manager.Report(), "Report");
这就是奇怪的地方。如果我放置 dialog.Popup.IsOpen = false;在 MessageBox 之后,(只是为了测试 DoWork 不是瞬时的——虽然我知道它不是)当 MessageBox 打开时弹出窗口是打开的。不是在 DoWork 之前。
它拒绝在 DoWork 之前打开。如果我删除 DoWork 并放置 Thread.Sleep(2000),同样的问题。弹出窗口在睡眠之后才会变得可见,即使声明是在之前。
如果我删除所有内容并只执行一个很长的 while 循环,则什么也没有。弹出窗口拒绝打开,直到循环结束。
有什么想法吗?
编辑:要添加,经过一些调试后,直到函数退出时它才可见(当我删除 MessageBox.Show 时)。
IE:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
...
}
// popup opens here
使用消息框:
DoWorkClicked()
{
dialogPopup.IsOpen = true;
DoWork()
MessageBox.BlahBlahBlah // Popup opens here
...
}
答案编辑:Theodosius Von Richthofen 回答了我的问题。添加了 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;
}
我相信您需要使用 BackgroundWorker 或类似工具(较新版本的 .NET 有一些新选项 Async/await 等),这可能都在 UI 线程上。这将使 UI 在工作完成之前更新,有效地显示然后不显示它,并且在完成所有操作之前它不会更新。您使用的是什么 .NET 框架?这是一个示例,请参阅已接受的答案...
How to correctly implement a BackgroundWorker with ProgressBar updates?
WPF ProgressBar usage when using Async/Await
超级简单的 .NET 4.5 示例:
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);
}