Emulate ShowDialog for Winforms UserControl
I would like to achieve the same effect like in this article but for windows forms, is it even possible without hosting the control on different Form?
EDIT I'm more interested in implementing the exact behavior of the control in the article, showing the control on the form and blocking the calling function, but without usi开发者_JAVA技巧ng other form for this purpose.
You can create a UserControl with the two buttons and the label for the message, then set its visibility to false in the constructor:
public MyDialog()
{
InitializeComponent();
Visible = false;
}
Then you add three variables to the control:
Form _parent;
bool _result;
bool _clicked = false;
the parent Form will be the Form your control is contained in and must be set before using the control, since it has to know what has to be disabled.
public void SetParent(Form f)
{
_parent = f;
}
_result will contain the result of the dialog, and _clicked will be used to determine when to close your dialog. What has to be done when you show your dialog is:
- set the label
- disable the form (but not the dialog)
- make the dialog visible
- wait for the user to click one of the buttons
- hide the dialog
- reenable the parent form
- return the result
So you could add this method to enable/disable the parent form:
private void ParentEnabled(bool aBool)
{
if (_parent == null)
return;
foreach (Control c in _parent.Controls)
if (c != this)
c.Enabled = aBool;
}
and use it in the ShowDialog method:
public bool ShowDialog(string msg)
{
if (_parent == null)
return false;
// set the label
msgLbl.Text = msg;
// disable the form
ParentEnabled(false);
// make the dialog visible
Visible = true;
// wait for the user to click a button
_clicked = false;
while (!_clicked)
{
Thread.Sleep(20);
Application.DoEvents();
}
// reenable the form
ParentEnabled(true);
// hide the dialog
Visible = false;
// return the result
return _result;
}
Obviously the buttons have the responsibility to set the _result and _clicked variables:
private void okBtn_Click(object sender, EventArgs e)
{
_result = true;
_clicked = true;
}
private void cancelBtn_Click(object sender, EventArgs e)
{
_result = false;
_clicked = true;
}
How about creating transparent form that in the middle contains text on opaque shape (whatever you like). Then at runtime you would resize this form to have same size as the window over which you want to display it and place it so that it covers it.
精彩评论