我有一个使用拆分容器的多标签winform。在右侧选项卡中,我使用左侧选项卡显示/隐藏用户控件。某些用户控件需要在其上显示新的用户控件。问题是当原始用户控件显示新的用户控件时,我希望第一个用户控件等待新的用户控件关闭(有些像表单中的ShowDialog),但是这个屏幕锁定只会在一个选项卡中出现。
我尝试了Threads和许多其他解决方案,但没有一个按我的意愿工作。
{
var panel = (Panel)this.Parent;
var searchUserControl = new searchUserControl();
searchUserControl.Parent = this;
panel.Controls.Add(searchUserControl);
this.visible = false; // hides the original form
// wait
this.visible = true; // shows the original form again
var result = searchUserControl.CustomProperty;
}
答案 0 :(得分:1)
如果您使用一些技巧,可以使用async
/ await
来执行此操作。
关键因素是TaskCompletionSource
。它代表Task
的“状态”,并允许您从代码中的另一个点“完成”它,在这种情况下,是“对话框”上的一个按钮。
创建一个UserControl
来代表您的“对话框”,给它“确定”和“取消”按钮,或者您需要的任何按钮。
UserControl
的代码隐藏应该如下所示:
public partial class DialogControl : UserControl
{
TaskCompletionSource<DialogResult> _tcs;
public DialogControl()
{
InitializeComponent();
this.Visible = false;
}
public Task<DialogResult> ShowModalAsync()
{
_tcs = new TaskCompletionSource<DialogResult>();
this.Visible = true;
this.Dock = DockStyle.Fill;
this.BringToFront();
return _tcs.Task;
}
private void btmCancel_Click(object sender, EventArgs e)
{
this.Visible = false;
_tcs.SetResult(DialogResult.Cancel);
}
private void btnOk_Click(object sender, EventArgs e)
{
_tcs.SetResult(DialogResult.OK);
this.Visible = false;
}
public string UserName
{
get { return txtName.Text; }
set { txtName.Text = value; }
}
}
主窗体上的Button
可以使用此代码显示“模态控件”:
private async void btnShowDialogControl_Click(object sender, EventArgs e)
{
var control = new DialogControl();
splitContainer1.Panel2.Controls.Add(control);
//Disable your other controls here
if (await control.ShowModalAsync() == DialogResult.OK) //Execution will pause here until the user closes the "dialog" (task completes), just like a modal dialog.
{
MessageBox.Show($"Username: {control.UserName}");
}
//Re-enable your other controls here.
splitContainer1.Panel2.Controls.Remove(control);
}
可以从here下载完整的工作解决方案源代码。