我有一个WPF应用程序来运行测试用例并收集结果。在主窗口上,使用可以选择一些测试用例并循环运行它们。运行案例时,会弹出一个自定义子窗口并向用户显示一些数据,然后用户点击“传递”按钮或“失败”来设置此测试用例的结果并关闭这个子窗口。然后下一个测试用例开始运行。在主窗口中,有一个“停止”按钮。用户可以点击它以在当前轮次结束后停止循环测试。 代码如下:
while (!stopByUser)
{
foreach(var caseItem in caseList)
{
// on TestWindow UI, caseItem.isPassed will be set by user with clicking buttons;
caseItem.isPassed = false;
TestWindow tw = new TestWindow(caseItem);
tw.ShowDialog();
if (caseItem.isPassed)
{
totalPassed++;
// update UI ...
}
}
}
问题是用户无法点击主窗口上的“停止”按钮,因为我使用tw.ShowDialog()来弹出模态窗口。但是,我也不能简单地将它改为tw.Show()来弹出一个非模态窗口,因为foreach循环中的代码必须同步执行。
我发现本机MessageBox具有以下功能:阻止代码而不阻止主窗口。例如
var result= MessageBox.Show(message, "Is this test case passed?", MessageBoxButton.YesNo);
// the following line will be executed after the MessageBox is closed
// and meanwhile I can operate my main window when the MessageBox is still visible
var passed = (judgement == MessageBoxResult.Yes);
所以我的问题是如何在.net 4.0中使用WPF窗口来实现此功能? 我的应用程序将在Windows XP上运行,因此.net 4.0是必需的。
有什么想法吗?提前谢谢!
答案 0 :(得分:0)
MessageBox.Show会阻止所有窗口,因为它使用ShowDialog方法。你能做的就是写逻辑:
示例:
private bool stopByUser {get;set;}
private int currentItemIndex {get;set;}
private List<object> caseList {get;set;}]
private TestWindow tw {get;set;
public void OnLoaded(object sender, RoutedEventArgs e)
{
ShowNext();
}
private void ShowNext()
{
if (stopByUser) return;
var caseItem = caseList[currentItemIndex++]
caseItem.isPassed = false;
tw = new TestWindow(caseItem);
tw.Closed += (s, e) =>
{
if (caseItem.isPassed)
{
totalPassed++;
// update UI ...
ShowNext();
}
};
tw.Show();
}
答案 1 :(得分:0)
感谢@Noseratio和@ VMaleev的帮助,我最终得到了一个使用Microsoft.Bcl.Async和async / await的解决方案。它不漂亮,但它有效。
while (!stopByUser)
{
foreach(var caseItem in caseList)
{
caseItem.isPassed = false;
GlobalVar.isFinished = false; // static variable: isFinished
TestWindow tw = new TestWindow(caseItem);
tw.Closed += (s, e) =>
{
GlobalVar.isFinished = true;
};
Task task = new Task(() =>
{
while (!GlobalVar.isFinished)
{
Thread.Sleep(100);
}
});
task.Start();
tw.Show();
await task;
// get the test result here from GlobalVar.isPassed
var passed = caseItem.isPassed;
// do other things
}
}
请记住,要使用Microsoft.Bcl.Async,必须在xp / win7上安装.NET Framework 4.0( KB2468871 )。查看更多here