简体   繁体   中英

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 using 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:

  1. set the label
  2. disable the form (but not the dialog)
  3. make the dialog visible
  4. wait for the user to click one of the buttons
  5. hide the dialog
  6. reenable the parent form
  7. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM