我正在创建一个应用程序,我希望实现一个进程窗口,该窗口在进行冗长的过程时出现。
我创建了一个标准的Windows窗体项目,我使用默认窗体创建了我的应用程序。我还创建了一个新表单作为进度窗口。
当我使用:
打开进度窗口(在函数中)时出现问题ProgressWindow.ShowDialog();
当遇到这个命令时,焦点在进度窗口上,我认为它现在是正在为事件处理主循环的窗口。缺点是它阻止了我在主窗体中执行冗长的操作。
如果我使用以下方式打开进度窗口:
ProgressWindow.Show();
然后窗口打开正确,现在不会阻止主窗体的执行,但它不作为子窗口(模态)应该,即允许选择主窗体,不以父窗口为中心等等。
我是如何打开新窗口但继续以主窗体处理的想法?
答案 0 :(得分:11)
您可能在单独的工作线程中开始冗长的操作(例如,使用后台工作程序)。然后使用ShowDialog()
显示您的表单,并在完成该主题后关闭您正在显示的对话框。
以下是一个示例 - 我假设您有两种形式(Form1
和Form2
)。在Form1
我从工具箱中提取了BackgroundWorker
。然后我将RunWorkerComplete
的{{1}}事件连接到我表单中的事件处理程序。以下是处理事件并显示对话框的代码:
BackgroundWorker
答案 1 :(得分:3)
另一种选择:
使用ProgressWindow.Show()
&自己实现模态窗口行为。 parentForm.Enabled = false
,自己定位表单等。
答案 2 :(得分:3)
我为另一个项目实现了与此类似的东西。此表单允许您从工作线程中弹出模式对话框:
public partial class NotificationForm : Form
{
public static SynchronizationContext SyncContext { get; set; }
public string Message
{
get { return lblNotification.Text; }
set { lblNotification.Text = value; }
}
public bool CloseOnClick { get; set; }
public NotificationForm()
{
InitializeComponent();
}
public static NotificationForm AsyncShowDialog(string message, bool closeOnClick)
{
if (SyncContext == null)
throw new ArgumentNullException("SyncContext",
"NotificationForm requires a SyncContext in order to execute AsyncShowDialog");
NotificationForm form = null;
//Create the form synchronously on the SyncContext thread
SyncContext.Send(s => form = CreateForm(message, closeOnClick), null);
//Call ShowDialog on the SyncContext thread and return immediately to calling thread
SyncContext.Post(s => form.ShowDialog(), null);
return form;
}
public static void ShowDialog(string message)
{
//Perform a blocking ShowDialog call in the calling thread
var form = CreateForm(message, true);
form.ShowDialog();
}
private static NotificationForm CreateForm(string message, bool closeOnClick)
{
NotificationForm form = new NotificationForm();
form.Message = message;
form.CloseOnClick = closeOnClick;
return form;
}
public void AsyncClose()
{
SyncContext.Post(s => Close(), null);
}
private void NotificationForm_Load(object sender, EventArgs e)
{
}
private void lblNotification_Click(object sender, EventArgs e)
{
if (CloseOnClick)
Close();
}
}
要使用,您需要从GUI线程中的某个位置设置SyncContext:
NotificationForm.SyncContext = SynchronizationContext.Current;