所述Form.ShowDialog()方法将导致被停止的代码,直到新称为形式被关闭。 我需要的代码的ShowDialog()方法被调用后继续运行。 我用Google搜索和阅读有关使用BackgroundWorker的? 但是,这是我第一次听说过这一点,从来没有使用过它。
Form2 form2this = new Form2();
form2this.ShowDialog();
MessageBox.Show("Something");
该代码被点击一个按钮后执行的,我怎么能还叫的ShowDialog以防止用户从与主窗体交互,但仍然允许的主要形式继续开展工作?
很抱歉,如果它被讨论,但一切,我发现似乎很难执行这样一个简单的任务。 我其实感到惊讶它不包括在ShowDialog方法。 例如ShowDialog的()。继续会很酷。
只要你在该模式对话框被打开的时间做异步操作,你可以简单地做到这一点,如下图所示,假设的button1_Click()是一个按钮的事件处理程序。
private async void button1_Click(object sender, EventArgs e)
{
// create and display modal form
Form2 modalForm = new Form2();
BeginInvoke((Action)(() => modalForm.ShowDialog()));
// do your async background operation
await DoSomethingAsync();
// close the modal form
modalForm.Close();
}
private async Task DoSomethingAsync()
{
// example of some async operation....could be anything
await Task.Delay(10000);
}
我发现,当我使用的建议使用展()的解决方案,我可以在该对话框我想是模式最终会主要形式的背后,来回切换应用程序之间的情况后结束。 当我使用上面的解决方案,它从未发生过。
是否有任何理由,你为什么不能有这样的代码为窗体2类的一部分? 或者使用一个无模式对话框? 你可以使用一个后台工作,甚至一些简单的像一个计时器,但似乎是大材小用?
运行一个异步调用显示模式。 在这里,在WPF一个例子:
private Window waitView;
/// <summary>
/// Closes a displayed WaitView from code.
/// </summary>
public void CloseWaitView()
{
if(waitView != null)
{
// Work on the gui Thread of waitView.
waitView.Dispatcher.Invoke(new Action(() => close()));
}
}
/// <summary>
/// Closes a displayed WaitView and releases waitView-Instance.
/// </summary>
private void close()
{
waitView.Close();
waitView = null;
}
/// <summary>
/// Showes a modal WaitView (Window).
/// </summary>
public void ShowWaitView()
{
// instance a new WaitViewWindow --> your Window extends Window-Class
waitView = new WaitViewWindow();
// prepare a operation to call it async --> your ShowDialog-call
var asyncCall = new Action(() => waitView.Dispatcher.Invoke(
new Action(() => waitView.ShowDialog())
));
// call the operation async
// Argument 1 ar:
// ar means IAsyncResult (what should be done, when come back from ShowDialog -->
// remove view memory with set waitView to null or ... dispose
// the second argument is an custom parameter you can set to use in ar.AsyncState
asyncCall.BeginInvoke(ar => waitView = null, null);
// all from here is done during ShowDialog ...
}
这是我的路,这么难看,但我没有更好的主意。
private void AppUiMain_Shown(object sender, EventArgs e)
{
var loading = new AppUiLoading();
loading.Shown += (o, args) =>
{
bool isLoading = true;
loading.Top = (int)(loading.Top * 1.16);
Application.DoEvents();//refresh ui
EventHandler ehr = null;
EventHandler ehe = null;
ehr = (ss, ee) =>
{
App.Instance.Ready -= ehr;
App.Instance.Error -= ehe;
isLoading = false;
};
ehe = (ss, ee) =>
{
loading.Text = "Error";
loading.ShowAbortButton("Error occur");
};
App.Instance.Error += ehe;
App.Instance.Ready += ehr;
InitApp();
//HACK: find a better way to `refresh' main form
Application.DoEvents();
this.Height++;
this.Height--;
//HACK: find a better way to keep message looping on ShowDialog
while (isLoading)
Application.DoEvents();
loading.Close();
};
loading.ShowDialog(this);
}
要继续执行代码,而不关闭模态对话框WindowsFormsSynchronizationContext.Current.Post( - => { “您的代码”},NULL); 可以使用。 在这里,你可以找到更多的细节 -
http://newapputil.blogspot.in/2015/05/continue-executing-code-after-calling.html
我想对于异步未来解决方案ShowDialog
:
public bool DialogResultAsync
{
get;
private set;
}
public async Task<bool> ShowDialogAsync()
{
var cts = new CancellationTokenSource();
// Attach token cancellation on form closing.
Closed += (object sender, EventArgs e) =>
{
cts.Cancel();
};
Show(); // Show message without GUI freezing.
try
{
// await for user button click.
await Task.Delay(Timeout.Infinite, cts.Token);
}
catch (TaskCanceledException)
{ }
}
public void ButtonOkClick()
{
DialogResultAsync = true;
Close();
}
public void ButtonCancelClick()
{
DialogResultAsync = false;
Close();
}
而在主窗体,您必须使用此代码:
public async void ShowDialogAsyncSample()
{
var msg = new Message();
if (await msg.ShowDialogAsync())
{
// Now you can use DialogResultAsync as you need.
System.Diagnostics.Debug.Write(msg.DialogResultAsync);
}
}