将TextBox值移动到其他

时间:2014-04-27 17:44:13

标签: c# winforms

我有一个winform C#app,我有一个问题。 首先是我的形式的图像。(它还不是最终的。所以对齐设置不正确。) Image.

这是我的问题。 有36个文本框(包含在红色区域内。)它们将保持最多12个值,但不是顺序,即一个接一个。 现在在蓝色区域是我想要的12个值将填充在红色区域。

我彻底搜查过,但找不到具体的东西。我写了一个代码,首先检查文本框是否是免费的,如果在切换按钮事件下将文本框值从红色区域免费复制到蓝色(以广泛的方式。)。它只会将最后几个文本框从这里复制到那里。

红色区域有36个文本框,蓝色区域只有12个,我不知道如何进一步了解。

感谢任何和所有帮助。

2 个答案:

答案 0 :(得分:1)

至少有两种方法可以达到这个效果。

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属性中的一个对象?)来了解谁是谁,那么名字可以是你想要的任何东西。

答案 1 :(得分:0)

您可以使用LINQ获取文本框。

首先,您需要为文本框指定名称,然后识别它们,并使用其名称区分红色区域和蓝色区域。

例如,红色区域中文本框的名称可以以红色开头,蓝色以蓝色开头。(这当然很可怕,我说的是例如,你不这样做可以为你的文本框提供更有意义的名字。)

这样做之后就是解决方案:

var values = this.Controls
            .OfType<TextBox>()
            .Where(x => x.Name.StartsWith("Red") && x.Text != string.Empty)
            .Select(x => x.Text)
            .ToList();

int i = 0;
foreach (var txtBox in this.Controls.OfType<TextBox>()
            .Where(x => x.Name.StartsWith("Blue")))
{
    txtBox.Text = values[i++];
}