Reputation: 1362
I have a multi tabs winform using a split container. In the right tab I show/hide the user controls using the left tab. Some user controls needs to show a new user control on top of it. The problem is that when the original user control shows the new user controls, I would like that the first user control waits the new one to close (some like ShowDialog in forms), but this screen lock should occour in only one tab.
I tried Threads and many other solutions but none works as I want.
{
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;
}
Upvotes: 1
Views: 1640
Reputation: 16991
You can use async
/await
to do this, if you use a few tricks.
The key ingredient is TaskCompletionSource
. It represents the "state" of a Task
, and lets you "complete" it from another point in code, in this case, a button on the "dialog".
Create a UserControl
to represent your "dialog", give it "ok" and "cancel" buttons, or whatever buttons you need.
The code-behind for the UserControl
should look something like this:
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; }
}
}
The Button
on the main form can use this code to display the "modal control":
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);
}
Full source code for a working solution can be downloaded from here.
Upvotes: 2