2017-08-20 249 views
-1

大家好这里我尽量让方法,可以在表单上循环,并从只读=真正的转换任何文本框enter image description here被只读=假,但它不工作只读属性

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

    } 
+3

_“它不工作” _ - 甚至不是接近,其中一个具体足够问题陈述。请修复您的问题,以便更清楚。提供一个好的[mcve],可以可靠地再现你遇到的任何问题,并且精确详细地描述这个问题。解释你具体遇到什么困难。 –

+0

试试这个:'(item as TextBox).ReadOnly = false;' – ja72

回答

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

代码是非常自我解释,但你应该通过流走明白它在做什么。

+1

递归解决方案比明确更容易阅读和理解队列。 –

+0

只是提供其他选项。 – Nkosi

0

您需要是递归的。表单控件可以包含其他控件。

+0

所以我做了如果只循环在文本框,当我键入item.readonly = false我得到erroe –

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