gpt4 book ai didi

c# - 从另一个表单更新对话框

转载 作者:太空宇宙 更新时间:2023-11-03 11:17:38 26 4
gpt4 key购买 nike

我知道那里有很多类似的问题,我已经通读了很多。不幸的是,在通读它们之后我仍然无法解决我的问题——但是我对 C# 还比较陌生。根据docs使用调试器时,线程不安全的问题会导致 InvalidOperationException。我的问题不是这种情况。

我用一个简单的原始测试类重新创建了问题以专注于我的问题。

主窗体应该显示一种进度对话框。

public partial class ImportStatusDialog : Form
{
public ImportStatusDialog()
{
InitializeComponent();
}

public void updateFileStatus(string path)
{
t_filename.Text = path;
}

public void updatePrintStatus()
{
t_printed.Text = "sent to printer";
}

public void updateImportStatus(string clientName)
{
t_client.Text = clientName;
}

public void updateArchiveStatus()
{
t_archived.Text = "archived";
}
}

当在主窗体中没有任何 Invoke() 调用该代码时:

private void button1_Click(object sender, EventArgs e)
{
ImportStatusDialog nDialog = new ImportStatusDialog();

nDialog.Show();

nDialog.updateFileStatus("test");
Thread.Sleep(1000);
nDialog.updateImportStatus("TestClient");
Thread.Sleep(1000);
nDialog.updatePrintStatus();
Thread.Sleep(1000);
nDialog.updateArchiveStatus();
Thread.Sleep(1000);

nDialog.Close();
}

即使我这样调用它:

private void button3_Click(object sender, EventArgs e)
{
ImportStatusDialog nDialog = new ImportStatusDialog();

nDialog.Show();

if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateFileStatus("Test");
});
}
else
{
nDialog.updateFileStatus("Test");
}

Thread.Sleep(1000);

if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updatePrintStatus();
});
}
else
{
nDialog.updatePrintStatus();
}

Thread.Sleep(1000);

if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateImportStatus("cName");
});
}
else
{
nDialog.updateImportStatus("cName");
}

Thread.Sleep(1000);

if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateArchiveStatus();
});
}
else
{
nDialog.updateArchiveStatus();
}

Thread.Sleep(1000);

nDialog.Close();
}

设计器中的对话框(在我的示例中)

designer view

会这样显示:

dialog at runtime

当我使用 ShowDialog() 时而不是 Show()对话框正确显示,但正如 API 文档指出的那样

You can use this method to display a modal dialog box in your application. When this method is called, the code following it is not executed until after the dialog box is closed

这不是我想要的,尤其是因为这意味着对话框更新只会在再次关闭后发生。

我在这里做错了什么?这似乎是一个微不足道的问题,但解决方案却让我望而却步。请记住,我是 C# GUI 编程的新手。

此外,我想问一下使用 Invoke() 的正确位置是什么?在调用对话框方法时,您会在主窗体中使用它还是在对话框更新方法本身中使用它?

最佳答案

看起来你在这里使用的不是多线程,所以调用的东西不是必需的。只有跨线程调用才需要调用 - 您正在创建多个表单,但您的所有代码都在同一个线程中运行。

如果您在主 UI 线程中进行工作(正如按钮单击事件中的代码所暗示的那样),则只需定期调用 Application.DoEvents() 以允许进度表刷新。

更好的解决方案是使用 BackgroundWorker为您的工作,并让它定期报告其进度。

然后您可以在 BackgroundWorker 的 ProgressChanged 事件中更新进度表(它将在主线程中执行,因此您仍然不必调用任何东西)。

关于c# - 从另一个表单更新对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12168174/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com