开发者

C# / Winforms: Copy string from a textbox to an existing array

开发者 https://www.devze.com 2023-02-20 05:24 出处:网络
Hey! I am trying to put some data from a textbox to an existing array. Basically when I double click a node, the program will split the information from a text file to an array, parts[], and search f

Hey! I am trying to put some data from a textbox to an existing array.

Basically when I double click a node, the program will split the information from a text file to an array, parts[], and search for the relevant data to display in the textboxes.

Say the users make changes in the textboxes, I would like to read the information and put it back into parts[] and join back parts[] to a string and save it back to the original text file. (My code follows below.) When I run it, an error says Index was outside the bounds of the array. Did I do something wrong?

[edited] Here the full code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    private Field[] fieldArray = new Field[100];
    private string[] parts;

    public Form1()
    {
        InitializeComponent();
    }

    private void populateTree(string path, TreeNode tv1)
    {
        string[] dir = Directory.GetDirectories(path);
        foreach (string d in dir)
        {
            string entry = Path.GetFileName(d);
            TreeNode t = tv1.Nodes.Add("Folder", entry, 0);
            populateTree(d, t);
        }
        string[] files = Directory.GetFiles(path);
        foreach (string f in files)
        {
            string entry = Path.GetFileName(f);
            tv1.Nodes.Add(f, entry, 1);
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //populate the tree
        TreeNode t = treeView1.Nodes.Add("Units");
        populateTree(@"..\units\", t);

        for (int i = 0; i < 100; i++)
        {
            fieldArray[i] = new Field();
        }
        fieldArray[0].label = new Label();
        fieldArray[0].label.AutoSize = true;
        fieldArray[0].label.Location = new System.Drawing.Point(323, 9);
        fieldArray[0].label.Name = "Programtittle";
        fieldArray[0].label.Text = "UAI UnitDef Editor";
        this.Controls.Add(fieldArray[0].label);

        fieldArray[0].save = new Button();
        fieldArray[0].save.Location = new System.Drawing.Point(549, 404);
        fieldArray[0].save.Name = "Save";
        fieldArray[0].save.Size = new System.Drawing.Size(75, 23);
        fieldArray[0].save.Text = "Save";
        fieldArray[0].save.UseVisualStyleBackColor = true;
        this.Controls.Add(fieldArray[0].save);
        this.fieldArray[0].save.Click += new System.EventHandler(this.Save_Click);

        int clabel = 36;
        fieldArray[1].varName = new string[] { "unitname", "name", "buildCostEnergy", }; //define labels

        //popluate label
        for (int i = 0; i < fieldArray[i].varName.Length; i++)
        {
            fieldArray[1].label = new Label();
            fieldArray[1].label.AutoSize = true;
            fieldArray[1].label.Location = new System.Drawing.Point(323, clabel);
            fieldArray[1].label.Name = "label";
            this.Controls.Add(fieldArray[1].label);
            fieldArray[1].label.Text = fieldArray[1].varName[i];
            clabel = clabel + 26;
        }

        //populate textbox 
        int cbox = 33;
        for (int i = 0; i < fieldArray[i].varName.Length; i++) 
        {

            fieldArray[i].txtBox = new TextBox();
            fieldArray[i].txtBox.Location = new System.Drawing.Point(410, cbox);
            fieldArray[i].txtBox.Name = "txtBox";
            fieldArray[i].txtBox.Size = new System.Drawing.Size(100, 50);
            this.Controls.Add(fieldArray[i].txtBox);

            cbox = cbox + 26;
        }
    }

    private void populateLabelTxtBo开发者_StackOverflow中文版x(string path)
    {
        //f.txtBox.Multiline = true; //added for testing purpose; 

        //read,split file 
        string text = System.IO.File.ReadAllText(path);
        char[] delimiters = new char[] { '{', '=', ';', '}' };
        parts = text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
        //fieldArray[1].varName = new string[] { "unitname", "name", "buildCostEnergy", };

        //display info in textbox 
        int a;
        int strNumber;
        int strIndex = 0;

        for (a = 0; a < fieldArray[1].varName.Length; a++)
        {
            for (strNumber = 0; strNumber < parts.Length; strNumber++)
            {
                strIndex = parts[strNumber].IndexOf(fieldArray[1].varName[a]);
                if (strIndex >= 0)
                    break;
            }

          strNumber = strNumber + 1;
          fieldArray[a].join = new int[]{strNumber};
          fieldArray[a].txtBox.Text = parts[strNumber]; 
        }

    }

    private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
    {
        if (treeView1.SelectedNode.Name != "Folder")
        {
            string text = System.IO.File.ReadAllText(treeView1.SelectedNode.Name);
            //f.txtBox.Text = text;
            populateLabelTxtBox(treeView1.SelectedNode.Name);
        }
    }

    private void Save_Click(object sender, EventArgs e)
    {
        //fieldArray[0].txtBox.Text = "Happy"; //on click save happy is display testing 
        //join[a] > holds number where item is taken 
        //parts[] store split text 

        for (int a = 0; a < fieldArray[1].varName.Length; a++)
        {
            parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
        }
        //join parts[] up with . as connector 
        string combine = string.Join(".", parts);
        fieldArray[0].txtBox.Text = combine;

    }

}
}

there is also the code of the fields:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
class Field
{
    public string[] varName;
    public TextBox txtBox;
    public Label label;
    public ToolTip tip;
    public Button save;
    public int[] join;

    public Field()
    {
        varName= new string[3];
        txtBox = null;     
        label = null;
        tip = null;
        save = null;
        join = new int[3];

    }

}
}


First, sorry that this will be quite lengthy. I've written this as I went through your code and tried to understand it (rather unsuccessfully, by the way). First, I'll just tell you where I think the problem lies:

First the brief conclusion:

    for (int a = 0; a < fieldArray[1].varName.Length; a++)
    {
        parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
        //                      ^^^
        //            this might be the problem.
    }

I suspect that a always runs from 0 to 2, while join might be an array with only 1 element, ie. the only valid index would be 0. This is due to an assignment in your method populateLabelTxtBox:

   fieldArray[a].join = new int[]{strNumber};
   //                            ^^^^^^^^^^^
   //              only one element in 'fieldArray[i].join'

And now for a long-ish walkthrough:

Pardon me for saying first that your code has quite a few issues, but I'll try to concentrate on the one you asked about.

Let's look at the for loop in your Save_Click event handler where I suspect the IndexOutOfRangeException is thrown:

    for (int a = 0; a < fieldArray[1].varName.Length; a++)
    {
        parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
    }

The error could be caused by different array accesses. I went through the definitions and assignments to all these arrays — why do you need so many arrays, btw.? — to check their bounds.

  • fieldArray seems to have 100 items.
  • fieldArray[i].varName seems to have 3 items.
  • fieldArray[i].join also seems to have 3 items, if I base my judgment on the initialization code inside the Field class. (But this will turn out to be wrong further down; but please bear with me for the moment.)

Due to the second point made, I assume for now that your for loop counter a runs from 0 to 2. This means:

  • fieldArray[a] is probably OK, since fieldArray has room for 100 items and we're only looking at the first 3.
  • fieldArray[a].join[a] should also be OK, as it should have exactly 3 items and we're looking at all of them.

However, it is not clear whether parts[...] is a valid array access; this depends on two things:

  1. the number of items in parts, which depends on your input text file;
  2. the value of fieldArray[a].join[a], which is used as an index into parts.

fieldArray[a].join[a] must lie between 0 and the number of items in your input text file; so let's look at how join is actually populated. This seems to happen in populateLabelTxtBox:

for (a = 0; a < fieldArray[1].varName.Length; a++)
{
    for (strNumber = 0; strNumber < parts.Length; strNumber++)
    {
        strIndex = parts[strNumber].IndexOf(fieldArray[1].varName[a]);
        if (strIndex >= 0)
            break;
    }
   strNumber = strNumber + 1;
   fieldArray[a].join = new int[]{strNumber};
   fieldArray[a].txtBox.Text = parts[strNumber]; 
}

(By now I get the feeling that I could just chase after arrays and array indexes forever. Thus I suggest very strongly you re-think your code design to make it easier to understand and maintain.)

Two things seem suspect:

  • strNumber = strNumber + 1;
    (I must admit I don't understand your code well enough to see what you're doing here, so let's skip it.)

  • fieldArray[a].join =new int[]{strNumber};
    Which means fieldArray[a].join is now an array, not with 3, but with only 1 item! If you now look back at your Save_Click loop:

    for (int a = 0; a < fieldArray[1].varName.Length; a++)
    {
        parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
        //                 ^^^^^^^^
        //             this might now fail
    }
    

fieldArray[a].join[a] is no longer likely to work, because a might be any number between 0 and 2 while join only allows index 0.


I'm not sure I've got everything right, but I've shown you a way to go through your code to find the error. I've also shown that your code is quite misleading in some respects, e.g. that you initialize arrays to a certain capacity, which will actually change to something else later on.

I hope this all be of some help to you.

0

精彩评论

暂无评论...
验证码 换一张
取 消