C# / Winforms: Copy string from a textbox to an existing array
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 theField
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, sincefieldArray
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:
- the number of items in
parts
, which depends on your input text file; - the value of
fieldArray[a].join[a]
, which is used as an index intoparts
.
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 meansfieldArray[a].join
is now an array, not with 3, but with only 1 item! If you now look back at yourSave_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.
精彩评论