C#基于Web的WPF - Popup IsOpen无法正常工作

时间:2015-06-29 20:17:46

标签: c# wpf popup xbap

我一直在搜索StackOverflow并谷歌一段时间来回答这个问题,但没有一个答案好像回答了这个问题。

我有一个弹出窗口。我想要它做的只是显示“请等待......”,做一些代码,走开。没有趣的东西,只是简单。

这是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),同样的问题。直到睡眠之后,弹出窗口才会变得可见,即使声明是在之前。

如果我删除所有内容并且只是做了很长时间的循环,没有。弹出窗口在循环之后才会打开。

有什么想法吗?

编辑:要进行一些调试,在函数退出之前(当我删除了MessageBox.Show时)它才会被显示。

IE:

DoWorkClicked()
{
    dialogPopup.IsOpen = true;
    DoWork()
    ...
} 
 // popup opens here

使用MessageBox:

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;
}

1 个答案:

答案 0 :(得分:1)

我相信您需要使用BackgroundWorker或类似工具(较新版本的.NET有一些新选项Async / await等),这可能都在UI线程上。这样就可以在工作完成之前更新UI,有效地显示然后不显示它,并且在完成所有操作之后它不会更新。您使用的.NET Framework是什么?这是一个例子,看到接受的答案......

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);
        }