【问题标题】:How to change the readonly property false of textboxes in winform?如何更改winform中文本框的只读属性为false?
【发布时间】:2013-11-09 11:05:32
【问题描述】:

我们如何在一个winform中将所有文本框的ReadOnly属性更改为真到假我正在尝试使用此代码,但这提示我对象空引用错误...

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

        }
    } 

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

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

    这是修改后的 if 命令,您可以使用它来解决您的问题:

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

    所以我很抱歉我忽略了您的文本框可以包含在其他容器控件中。是的,这意味着您需要做 2 件事中的 1 件事: 1:您可以将 TextBoxes 移到 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.
        }
    }
    

    【讨论】:

    • 不工作!但是现在它没有提示错误。是因为文本框放在一个组框中吗?
    • @buddy,是的,在 GroupBox 中的 TextBoxes 是一个额外的复杂因素,这会导致我原来的答案缺失。我的错。我已更新我的答案,为您提供 2 个选项来解决此新问题。您真正需要做的就是添加 2 行代码。 :)
    【解决方案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;
    }
    

    【讨论】:

    • 斯蒂格,我也喜欢你的回答。这对某些人来说很复杂,但对于那些了解这段代码的人来说,它非常有用。所以我感谢你的(非常)好的解决方案,我也对你投了赞成票。我还提供了一个更基本的 C# 解决方案,更容易理解,适合那些想要简单方法而又不复杂的人。在这种情况下,我认为没有必要将这种延迟加载与yield 一起使用,但我希望有时这种解决方案会比我给出的替代简单解决方案更好。但对每个人都是他自己的(或她自己的)。祝大家编码愉快!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多