Bypass default behavior of showdialog

Shaifali jain 420 Reputation points
2023-10-06T02:51:40.0366667+00:00

Hi , I am looking for solution where a dialogbox (showdialog()) is a modal to just the parent control /form, and not the whole application. In other words , it should not allow the user to use it's parent form/control until dialog is closed but let the user to access other parts of the form .

Current windows ShowDialog() is insufficient for the needs of my application, as I need to have a dialog be modal to another control/form in the application, but still allow the user to access other areas of the application .

I tried searching Google but found nothing related to my needs .

Developer technologies Windows Forms
Developer technologies C#
{count} votes

2 answers

Sort by: Most helpful
  1. KOZ6.0 6,655 Reputation points
    2023-10-06T03:33:42.9566667+00:00

    Will your needs be met?

    private void button1_Click(object sender, EventArgs e) {
        var childForm = new ChildForm();
        childForm.FormClosed += ChildForm_FormClosed;
        childForm.Show(this);
        // Disable Parts
        button1.Enabled = false;
    }
    
    private void ChildForm_FormClosed(object sender, FormClosedEventArgs e) {
        var childForm = (ChildForm)sender;
        childForm.FormClosed -= ChildForm_FormClosed;
        // Enable Parts
        button1.Enabled = true;
    }
    

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-10-06T11:56:39.09+00:00

    ShowDialog should only be used when business requirements indicate that that form when open is the only form that can be used. Seems you should use Show and have methods to disable controls and enable controls.

    The following, placed in a public static class provide disable controls on a form with a param parameter for excluding controls from being disabled. This may or may not be suitable for what you want but perhaps if not the code can be helpful for other task.

    /// <summary>
    /// Disable all controls on a form
    /// </summary>
    /// <param name="parentControl">Form to work with</param>
    /// <param name="exclude">list of controls to exclude</param>
    public static void DisableControls(this Control parentControl, params string[] exclude)
    {
        var controls = parentControl.Descendants<Control>().ToList();
        if (exclude.Any())
        {
            foreach (var control in controls.Where(control => !exclude.Contains(control.Name)))
            {
                control.Enabled = false;
            }
        }
        else
        {
            foreach (var control in controls)
            {
                control.Enabled = false;
            }
        }
    }
    /// <summary>
    /// Enable all controls on a form
    /// </summary>
    /// <param name="parentControl"></param>
    public static void EnableControls(this Control parentControl)
    {
        parentControl.Descendants<Control>().ToList().ForEach(c => c.Enabled = true);
    }
    
    /// <summary>
    /// Base method for obtaining controls on a form or within a container like a panel or group box
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control"></param>
    /// <returns></returns>
    public static IEnumerable<T> Descendants<T>(this Control control) where T : class
    {
        foreach (Control child in control.Controls)
        {
            if (child is T thisControl)
            {
                yield return (T)thisControl;
            }
    
            if (child.HasChildren)
            {
                foreach (T descendant in Descendants<T>(child))
                {
                    yield return descendant;
                }
            }
        }
    }
    

    Example

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button3_Click(object sender, EventArgs e)
        {
            this.DisableControls("button1", "button3", "button4");
        }
    
        private void button4_Click(object sender, EventArgs e)
        {
            this.EnableControls();
        }
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.