I need to copy 160 textbox's text and put it onto the clipboard.

Here is what I have so far:

List<TextBox> boxes = new List<TextBox>() { textBoxX1, textBoxX2, textBoxX3, textBoxX4, textBoxX5, textBoxX4, textBoxX4, textBoxX5, textBoxX6, textBoxX7, textBoxX8, textBoxX9, textBoxX10, textBoxX11, textBoxX12, textBoxX13, textBoxX14, textBoxX15, textBoxX16, textBoxX17, textBoxX18, textBoxX19, textBoxX20, textBoxX21, textBoxX22, textBoxX23, textBoxX25, textBoxX26, textBoxX27, textBoxX28, textBoxX29, textBoxX30, textBoxX31, textBoxX32, textBoxX33, textBoxX34, textBoxX35, textBoxX36, textBoxX37, textBoxX38, textBoxX39, textBoxX40, textBoxX41, textBoxX42, textBoxX43, textBoxX44, textBoxX45, textBoxX46, textBoxX47, textBoxX48, textBoxX49, textBoxX50, textBoxX51, textBoxX52, textBoxX53, textBoxX54, textBoxX55, textBoxX56, textBoxX57, textBoxX58, textBoxX59, textBoxX60, textBoxX61, textBoxX62, textBoxX63, textBoxX64, textBoxX65, textBoxX66, textBoxX67, textBoxX68, textBoxX69, textBoxX70, textBoxX71, textBoxX72, textBoxX73, textBoxX74, textBoxX75, textBoxX76, textBoxX77, textBoxX78, textBoxX79, textBoxX80, textBoxX81, textBoxX82, textBoxX83, textBoxX84, textBoxX85, textBoxX86, textBoxX87, textBoxX88, textBoxX89, textBoxX90, textBoxX91, textBoxX92, textBoxX93, textBoxX94, textBoxX95, textBoxX96, textBoxX97, textBoxX98, textBoxX99, textBoxX100, textBoxX101, textBoxX102, textBoxX103, textBoxX104, textBoxX105, textBoxX106, textBoxX107, textBoxX108, textBoxX109, textBoxX110, textBoxX111, textBoxX112, textBoxX113, textBoxX114, textBoxX115, textBoxX116, textBoxX117, textBoxX118, textBoxX119, textBoxX120, textBoxX121, textBoxX122, textBoxX123, textBoxX124, textBoxX125, textBoxX126, textBoxX127, textBoxX128, textBoxX129, textBoxX130, textBoxX131, textBoxX132, textBoxX133, textBoxX134, textBoxX135, textBoxX136, textBoxX137, textBoxX138, textBoxX139, textBoxX140, textBoxX141, textBoxX142, textBoxX143, textBoxX144, textBoxX145, textBoxX146, textBoxX147, textBoxX148, textBoxX149, textBoxX150, textBoxX151, textBoxX152, textBoxX153, textBoxX154, textBoxX155, textBoxX156, textBoxX157, textBoxX158, textBoxX159, textBoxX160};
            var query = from textBoxX in boxes
            select textBoxX.Text;
            string combinedText = string.Join(string.Empty, query.ToArray());

Dani AI

Generated

started with a literal list and suggested creating/collecting controls instead of maintaining 160 names. Both approaches work, but a more robust pattern is: 1) collect the TextBox controls programmatically (recursively if some are inside panels), 2) choose a deterministic order (TabIndex or numeric suffix from the Name), 3) build the combined string with a StringBuilder (avoid repeated +=), and 4) set the clipboard with a resilient call (clipboard can be busy).

A compact, practical helper (works for WinForms) — find all TextBoxes, sort by trailing digits in the control Name (falls back to TabIndex), and produce a newline-separated result:

IEnumerable<TextBox> GetAllTextBoxes(Control parent)
{
    foreach (Control c in parent.Controls)
    {
        if (c is TextBox) yield return (TextBox)c;
        else
        {
            foreach (var child in GetAllTextBoxes(c))
                yield return child;
        }
    }
}

string BuildCombinedText(Control root)
{
    var rx = new System.Text.RegularExpressions.Regex(@"\d+$");
    var boxes = GetAllTextBoxes(root)
        .Select(tb => new { Tb = tb, Index = rx.Match(tb.Name).Success ? int.Parse(rx.Match(tb.Name).Value) : tb.TabIndex })
        .OrderBy(x => x.Index)
        .Select(x => x.Tb);

    var sb = new System.Text.StringBuilder();
    foreach (var tb in boxes)
    {
        if (!string.IsNullOrEmpty(tb.Text))
            sb.AppendLine(tb.Text); // change separator if needed
    }
    return sb.ToString();
}

When writing to the clipboard, prefer a retry loop to handle transient sharing violations:

void SetClipboardWithRetry(string text, int retries = 5)
{
    for (int i = 0; i < retries; i++)
    {
        try
        {
            System.Windows.Forms.Clipboard.SetDataObject(text, true);
            return;
        }
        catch (System.Runtime.InteropServices.ExternalException)
        {
            System.Threading.Thread.Sleep(50);
        }
    }
}

Notes and cautions: do not edit designer.cs by hand; create controls or collect them after InitializeComponent. Clipboard APIs are UI-thread (STA) only — if code runs off the UI thread you must marshal to an STA thread. If this is an ASP.NET scenario, server code cannot write to a client clipboard; use client-side JavaScript (navigator.clipboard.writeText) instead — see the Clipboard API docs for details (MDN clipboard.writeText, Microsoft Clipboard.SetDataObject).

Recommended Answers

All 3 Replies

Bloody hell.
Right after the form1:form, put:

TextBox[] textboxes = new TextBox[160]

Or, if you do not have a fixed amount, do it in a list, as in your example.
Under the InitializeComponent(), put:

for (int i = 0; i < 160 /*LIST.Count if you used a list*/; i++)
{
    TextBox textboxes[i] = new TextBox;
    textboxes[i].Tag = i; // Should you need to identify it
    // Set the parameters, such as width, height
    // Stack them on top of each other:
    textboxes[i].Top = i * textboxes[i].Height;
}

If you wish to get all the text, use:

private string GetText()
{
    string str = "";
    foreach (TextBox tb in textboxes)
        str += tb.Text;
    return str;
}

To set the clipboard text to that, use:

Clipboard.SetText(Getext());

I didn't type this in the IDE, so sorry about errors. This method is much better- having so many textboxes individually created is very messy.

commented: Good suggestion! +6

Could you revise this part?

for (int i = 0; i < 160 /*LIST.Count if you used a list*/; i++)
{
    TextBox textboxes[i] = new TextBox;
    textboxes[i].Tag = i; // Should you need to identify it
    // Set the parameters, such as width, height
    // Stack them on top of each other:
    textboxes[i].Top = i * textboxes[i].Height;
}

Could you revise this part?

for (int i = 0; i < 160 /*LIST.Count if you used a list*/; i++)
{
    TextBox textboxes[i] = new TextBox;
    textboxes[i].Tag = i; // Should you need to identify it
    // Set the parameters, such as width, height
    // Stack them on top of each other:
    textboxes[i].Top = i * textboxes[i].Height;
}

If you go into (expand the form in the solution browser), there should be a lot of stuff that creates the components. What I usually do is copy that code and paste it into the loop, and for stuff that is not consistent, such as the top, I just times a value by i, so that there is not a massive overlap. You will need to set the width.
I think I forgot to add, at the bottom (still in the loop), you must add

this.Controls.Add(textboxes[i]);

Otherwise it doesn't actually add it.
Hope this helps.

Just a quick note, if you're going to add events, in the event, to get the textbox, you would use the following:

private void TextBoxClick(object sender, EventArgs e)
{
((TextBox)sender).etc.
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.