There at least two ways to achieve that result.
1) You can group your text boxes using panels, one panel for text boxes filled by user and another one for text boxes with copied values. First get values from first group:
private static IEnumerable<string> GetValues(Panel container)
{
return container.Controls
.OfType<TextBox>()
.Select(x => x.Text)
.Where(x => !String.IsNullOrWhiteSpace(x));
}
Now you have an enumeration with strings from first group, let's put them in target controls:
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();
}
}
Used like this:
FillWith(pnlTarget, GetValues(pnlInputs));
2) Use some convention for names (for example name all textboxes with user inputs as txtInputXYZ
, where XYZ is an incrementing number, and all outputs with txtOutputXYZ
). Just loop thorugh them like this:
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;
}
If you don't know number of input and output textboxes (because they're dynamically added) or simply because you don't want to hard-code that (good) then:
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;
}
Both methods can be used as idea, you don't actually need to use LINQ (in case you're running on older .NET version, for example). In first method you can also skip Queue (but it's such micro-optimization...) and you may manually iterate through the enumeration (returning when end is reached). Moreover second method isn't tied to names, you can decorate them somehow (an object in the Tag
property?) to understand who is who then names can be anything you want.