我正在尝试创建一种方法来简单地清除网络表单中的所有文本框。
这是我正在调用的代码:
private void clearFrom()
{
IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>();
foreach (TextBox textBox in textBoxes)
{
textBox.Text = string.Empty;
}
}
它没有错误,只是永远不会打电话给textBox.Text = string.Empty;
我猜测文本框列表尚未创建,并怀疑我错过了重要的一步。我认为Controls.OfType<TextBox>()
我也尝试过使用以下内容:
private void clearFrom()
{
IEnumerable<TextBox> Textboxes = (from Control c in this.Controls
where c.GetType() == typeof(TextBox)
select c).AsEnumerable().Cast<TextBox>();
FunctionalExtensions.ForEach(Textboxes, ClearTextBox);
}
public static class FunctionalExtensions
{
public static void ForEach<T>(IEnumerable<T> items, Action<T> DoSomething)
{
foreach (T item in items)
{
DoSomething(item);
}
}
}
private void ClearTextBox(TextBox txtbox)
{
txtbox.Text = string.Empty;
}
同样,它没有错误,但从未调用ClearTextBox
。
我知道这是一个c#schoolboy错误,说实话,一分钱还没有说明IEnumerable
实际上在做什么。任何帮助将不胜感激。
答案 0 :(得分:2)
我认为以下内容对您有所帮助。它可以根据您的要求获得IEnumerable中的所有文本框。
致电部分
var c = GetAll(this, typeof(TextBox));
foreach (TextBox txt in c)
{
txt.Text = "";
}
功能
public IEnumerable<Control> GetAll(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl, type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
答案 1 :(得分:1)
Controls属性仅从顶部开始。您需要递归地逐步执行每个控件,并且它的子项可以找到所有文本框:
public static List<Control> GetAllControls(List<Control> controls, Type t, Control parent /* can be Page */)
{
foreach (Control c in parent.Controls)
{
if (c.GetType()== t)
controls.Add(c);
if (c.HasControls())
controls = GetAllControls(controls, t, c);
}
return controls;
}
答案 2 :(得分:1)
使用泛型来推导Josh的答案。
public static IEnumerable<T> GetAllControlsOfType<T>(Control parent) where T: Control {
foreach (Control c in parent.Controls) {
if (c is T)
yield return c as T;
if (c.HasControls())
foreach (T innerControl in GetAllControlsOfType<T>(c))
yield return innerControl;
}
}
答案 3 :(得分:1)
问题是你没有遍历整个控件的树。你刚刚得到直接的孩子。您可以编写一个简单的方法来让所有孩子通过整个控件的树,将其插入到您的代码中,并且它将起作用。
public static IEnumerable<Control> GetAllChildren(this Control root)
{
var stack = new Stack<Control>();
stack.Push(root);
while (stack.Any())
{
var next = stack.Pop();
foreach (Control child in next.Controls)
stack.Push(child);
yield return next;
}
}
使用此方法,您现在可以写:
private void clearFrom()
{
var textBoxes = this.GetAllChildren().OfType<TextBox>();
foreach (TextBox textBox in textBoxes)
{
textBox.Text = string.Empty;
}
}
我们甚至可以将此概括为Traverse
方法,该方法不是Control
特有的,并且能够遍历任何树:
public static IEnumerable<T> Traverse<T>(T item, Func<T, IEnumerable<T>> childSelector)
{
var stack = new Stack<T>();
stack.Push(item);
while (stack.Any())
{
var next = stack.Pop();
yield return next;
foreach (var child in childSelector(next))
stack.Push(child);
}
}
在这种情况下,这将被称为Traverse(this, c => c.Controls)
,但具有可与任何其他类型的树一起使用的好处。