如何在winform中更改文本框的readonly属性false?

时间:2013-10-30 02:21:56

标签: c# winforms

如何更改winform中所有textBox的ReadOnly属性为true,我正在尝试使用此代码,但这会提示我对象null引用错误...

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

        }
    } 

2 个答案:

答案 0 :(得分:6)

那是因为并非cc中的所有控件都是TextBoxes。因此,当您尝试将它们转换为TextBox时,该变量为null。当变量为null时,您无法访问该变量的任何属性,否则您将收到错误。因此,只要变量可以为null,您必须首先测试它是否为空。

以下是您要用来解决问题的修改过的if命令:

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

所以我道歉,我忽略了你的TextBox可以包含在其他容器控件中。是的,这意味着您需要执行以下两项操作之一:1:您可以将TextBox移动到GroupBox之外。哈哈。我只是在开玩笑。是的,这可以解决这个问题但是你会遇到更糟糕的问题。正确的方法是以递归方式为每个在Controls属性中具有控件的控件调用方法。每个控件都有此属性,但它似乎在非容器的控件中为空(但不为null)。 (我今天刚刚了解到每个控件都有Controls属性,所以我更新了我的代码以反映这一点。) 所以对于这个真正的解决方案,我建议类似于此:

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.
    }
}

答案 1 :(得分:2)

首先你要使用这样的函数:

Recursive get controls

然后你做以下

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;
}