至少有两种方法可以实现该结果。
1) 您可以使用面板对文本框进行分组,一个面板用于用户填写的文本框,另一个用于具有复制值的文本框。首先从第一组获取值:
private static IEnumerable<string> GetValues(Panel container)
{
return container.Controls
.OfType<TextBox>()
.Select(x => x.Text)
.Where(x => !String.IsNullOrWhiteSpace(x));
}
现在您有了一个包含第一组字符串的枚举,让我们将它们放入目标控件中:
private static void FillWith(Panel container, IEnumerable<string> values)
{
Queue<string> queue = new Queue<string>(values);
foreach (var textbox in container.Controls.OfType<TextBox>())
{
// Not enough values to fill all textboxes
if (queue.Count == 0)
return;
textbox.Text = queue.Dequeue();
}
}
这样使用:
FillWith(pnlTarget, GetValues(pnlInputs));
2) 对名称使用一些约定(例如,将用户输入的所有文本框命名为 txtInputXYZ,其中 XYZ 是递增数字,所有输出都使用 txtOutputXYZ)。像这样遍历它们:
for (int inputIndex = 0, outputIndex = 0; inputIndex < numberOfInputs; ++inputIndex)
{
string value = ((TextBox)Controls[String.Format("txtInput{0}", inputIndex)]).Text;
if (String.IsNullOrWhiteSpace(value))
continue;
var target = (TextBox)Controls[String.Format("txtOutput{0}", outputIndex++)];
if (target == null)
break; // No more targets
target.Text = value;
}
如果您不知道输入和输出文本框的数量(因为它们是动态添加的)或者只是因为您不想对其进行硬编码(很好),那么:
for (int inputIndex = 0, outputIndex = 0; ; ++inputIndex)
{
var source = Controls[String.Format("txtInput{0}", inputIndex)];
if (source == null)
break; // No more sources
string value = ((TextBox)source).Text;
if (String.IsNullOrWhiteSpace(value))
continue;
var target = (TextBox)Controls[String.Format("txtOutput{0}", outputIndex++)];
if (target == null)
break; // No more targets
target.Text = value;
}
这两种方法都可以用作想法,您实际上不需要使用 LINQ(例如,如果您在较旧的 .NET 版本上运行)。在第一种方法中,您也可以跳过队列(但它是这样的微优化......)并且您可以手动迭代枚举(到达结束时返回)。此外,第二种方法与名称无关,您可以以某种方式装饰它们(Tag 属性中的对象?)以了解谁是谁,然后名称可以是任何您想要的。