【问题标题】:Move TextBox Values to Other将文本框值移动到其他
【发布时间】:2014-04-28 02:21:54
【问题描述】:

我有一个 winform C# 应用程序,但我遇到了问题。 首先这是我的表格的图像。(它还不是最终的。所以对齐设置不正确。)

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

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

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

感谢任何和所有的帮助。

【问题讨论】:

    标签: c# winforms


    【解决方案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 属性中的对象?)以了解谁是谁,然后名称可以是任何您想要的。

    【讨论】:

    • 即使使用您编写的第二种方法,它仍然不会将数据复制到“蓝色区域”。我周围有一个组框,现在删除了,仍然没有输出
    • 同样,在您的第二种方法中,如果我在三个声明中的每一个上放置一个断点,一旦到达第一个断点,就会返回控件。意思是,循环不前进。
    • @REZR.AMX 我不能发布设计器代码(然后你必须根据你的可视化树把它放在你的上下文中): 1st)保留组框,只需将 Panel 替换为 @该函数中的 987654330@ (参数必须是该输入框的 direct 容器。2)循环内的第一行:您必须将 Controls 替换为适当的容器!如果它们在GroupBox (比如说grpFirst)内,则不能使用Controls (等于this.Controls),而是grpFirst.Controls。您也可以考虑将Controls["..."] 替换为Find("...", true),这将搜索所有可视化树。
    【解决方案2】:

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

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

    例如,红色区域的文本框名称可以以Red开头,蓝色以Blue开头。(这当然很可怕,我是说例如,您不会为您的文本框赋予更有意义的名称)。

    在你这样做之后,这是解决方案:

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

    【讨论】:

    • 这段代码没有输出,完全按照你说的做,数据仍然没有排列到“蓝色区域..”除此之外我还有什么需要做的吗?
    • “蓝色区域”控件包含在组框内。我把它们拿出来了,但它仍然不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多