我有一个带动画的表单,我在做一些其他表单的请求时显示。我正在做一些研究如何在请求中显示这个动画形式,并想出这样做:
public partial class ProcessingForm : Form
{
private static Thread processingFormThread;
public ProcessingForm()
{
InitializeComponent();
}
public void StartThreadOnProcessingForm()
{
processingFormThread = new Thread(() => { new ProcessingForm().ShowDialog(); });
processingFormThread.Start();
}
public void CloseThreadOnProcessingForm()
{
processingFormThread.Abort();
}
}
现在,当我需要使用表格时,我这样做:
public void Foo()
{
ProcessingForm pf = new ProcessingForm();
pf.StartThreadOnProcessingForm();
// some request/data actions
Form requestForm;
if (requestdata!= null)
{
requestForm = new requestForm(data);
pf.CloseThreadOnProcessingForm();
requestForm.Show();
requestForm.SetDataForForm(requestdata);
}
}
这就像一个非常简单的解决方案,但我在研究时没有看到类似的东西,所以感觉我做错了。我的问题是有更好的方法来做一个这样简单的事情吗?
答案 0 :(得分:1)
解决此问题的一种方法是将Action
传递给进度表单,并在进度表单的单独线程中执行该操作。操作完成后,关闭进度表单。
例如,您可以在进度表单中执行以下操作:
public partial class ProgressForm: Form
{
public ProgressForm(Action action)
{
_action = action;
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
Task.Factory.StartNew(() =>
{
_action();
_finished = true;
BeginInvoke(new Action(Close));
});
}
protected override void OnClosing(CancelEventArgs e)
{
// Prevent the user from closing the form until the action has completed.
if (!_finished)
e.Cancel = true;
}
private readonly Action _action;
private volatile bool _finished;
}
然后,当您想要等待一个长动作完成时,您可以像这样使用进度表单(此示例显示在主窗体中单击按钮时的进度表单,并且该操作只是一个虚拟函数,睡几秒钟来模拟工作):
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (var progress = new ProgressForm(action))
{
progress.ShowDialog();
}
}
static void action()
{
Thread.Sleep(10000);
}
}
答案 1 :(得分:0)
说实话,我并不真正理解你想要达到的目标,但有两个明显的问题:
开始一个新线程来调用ShowDialog
毫无意义。使用ShowDialog
而不是Show
的关键是创建一个模态对话框,阻止执行(当前线程)直到对话框关闭。在新线程中执行此操作会使整个目的失败。
如Matthew Watson所述,Abort
很糟糕。请参阅:What's wrong with using Thread.Abort()
我建议调用ProcessingForm
非模态(Show
),将其设为Topmost
并禁用其他形式(无线程)。然后在后台Task
(async
/ await
)中执行数据操作。任务完成后,关闭ProcessingForm
并重新启用其他表单。
答案 2 :(得分:0)
如果我理解得很好,你想要一个能够理解何时自动显示和关闭的弹出窗口。
一个简单的解决方案是轮询一个名为' Busy'的静态属性。如果为true则调用表单上的Show,如果为false则调用hide。您可以通过将逻辑置于“忙碌”中来避免轮询。财产制定者。
在主应用程序中,您只需在长时间运行操作之前设置Popup.Busy = true
,在完成操作时设置为false。
只需在新主题中启动弹出窗口。