只读属性

时间:2017-08-20 00:39:55

标签: c# winforms

大家好我在这里尝试制作可以在表单上循环并将任何文本框enter image description here从Read only = true转换为只读= false但不能正常工作的方法

public static void unread only(Form frm)
    {
        foreach (Control item in frm.Controls)
        {
            if (item is TextBox)
            {
               // item.ReadOnly = false;
            }
        }            

  }

3 个答案:

答案 0 :(得分:1)

在您的代码中,编译器认为您找到的对象是Control,并且不知道它是什么类型的控件。你需要告诉它它是什么类型的控制,你可以通过将其转换为文本框来实现:

((TextBox)item).ReadOnly = false;

但是,有更好的方法可以做到这一点。您的代码只会查看顶级控件,如果表单上有容器控件,则不会递归搜索这些控件以查找其他文本框。执行此操作的递归方法如下:

public static IEnumerable<T> GetControlsOfType<T>(Control root)
where T : Control
{
var t = root as T;
if (t != null)
    yield return t;

var container = root as ContainerControl;
if (container != null)
    foreach (Control c in container.Controls)
        foreach (var i in GetControlsOfType<T>(c))
            yield return i;
}

这是我从here获得的一些代码。它允许你做这样的事情:

foreach (var textBox in GetControlsOfType<TextBox>(theForm)) 
{
    textBox.ReadOnly = false;
}

答案 1 :(得分:0)

你需要递归。表单控件可以包含其他控件。

答案 2 :(得分:0)

主要是您的问题是您没有将控件转换为TextBox,以便您可以访问要设置的属性。

foreach (Control item in frm.Controls) {
    if (item is TextBox) {
        var textBox = item as TextBox;
        textBox.ReadOnly = false;
    }
}

也就是说,控件可以包含子控件,因此您需要抓取整个表单以查找嵌入的文本框。

这将检查文本框的表单及其控件,并将它们设置为只读

public static void SetReadOnly(Control frm) {
    var controls = new Queue<Control>();
    controls.Enqueue(frm);
    while (controls.Count > 0) {
        var control = controls.Dequeue();
        if (control is TextBox) {
            var txtBox = control as TextBox;
            txtBox.ReadOnly = true;
        }
        if (control.HasChildren) {
            foreach (var child in control.Controls.OfType<Control>()) {
                controls.Enqueue(child);
            }
        }
    }
}

代码非常自我解释,但您应该完成流程以了解它正在做什么。