Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the readonly property false of textboxes in winform?

Tags:

c#

winforms

How can we change the ReadOnly property of all textBoxes in a winform that is true to false i'm trying using this code but this prompt me object null reference error...

    private void TextBoxesReadOnlyTrue(Control.ControlCollection cc)
    {
        foreach (Control ctrl in cc)
        {
            TextBox tb = ctrl as TextBox;
            if (tb.ReadOnly)
             {
                tb.ReadOnly = false;
             }

        }
    } 
like image 284
buddy Avatar asked Feb 14 '23 20:02

buddy


2 Answers

That's because not all the controls in cc are TextBoxes. So when you try converting them to a TextBox, the variable is null. When a variable is null, you cannot access any properties on that variable, or you'll get an error. So anytime a variable can be null, you MUST first test whether it is null.

Here's the modified if command that you'll want to use to fix your problem:

    if (tb != null && tb.ReadOnly) { tb.ReadOnly = false; }

So i appologize that i overlooked that your TextBoxes can be contained in other container controls. Yes, that means you need to do 1 of 2 things: 1: You can move the TextBoxes outside the GroupBox. haha. I'm just joking. Yes, that can solve that problem but then you have worse problems. The correct way is to recursively call your method for every control that has controls in its Controls property. Every control has this property but it seems it is empty (but not null) in controls that are not containers. (I just learned today that every control has this Controls property, so i've updated my code to reflect this.) So for this real solution, i suggest something similar to this:

private void TextBoxesReadOnlyTrue(Control.ControlCollection cc)
{
    foreach (Control ctrl in cc)
    {
        TextBox tb = ctrl as TextBox;
        if (tb != null && tb.ReadOnly)
        { tb.ReadOnly = false; continue; }

        if (ctrl.Controls != null && ctrl.Controls.Count > 0)
        { TextBoxesReadOnlyTrue(ctrl.Controls); }
        // this recursively calls this same method for every control ...
        // that is a container control that contains more controls, ...
        // such as GroupBoxes, Panels, etc.
    }
}
like image 166
Shawn Kovac Avatar answered Feb 22 '23 22:02

Shawn Kovac


first you would like to use a function like this:

Recursive get controls

then you do the following

private IEnumerable<T> GetControls<T>(Control.ControlCollection ctrls)
{
    foreach (object ctrl in ctrls)
    {
        foreach (var item in GetControls<T>(((Control)ctrl).Controls))
        {
            yield return item;    
        } 
        if (ctrl is T)
           yield return (T)ctrl;

    }
}

foreach(var txtbox in  GetControls<TextBox>(form.Controls)
{
    txtbox.ReadOnly = false;
}
like image 31
Stig Avatar answered Feb 22 '23 23:02

Stig