喂!我试图将一些数据从文本框放到现有数组中。
基本上,当我双击一个节点时,程序会将信息从文本文件拆分为数组parts[]
,并搜索相关数据以显示在文本框中。
假设用户在文本框中进行了更改,我想阅读这些信息并将其重新放回parts[]
并将parts[]
连接回字符串并将其保存回原始文本文件。 (我的代码如下所示。)当我运行它时,错误说索引超出了数组的范围。我做错了吗?
[编辑] 这里是完整的代码:
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 populateLabelTxtBox(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;
}
}
}
还有字段的代码:
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];
}
}
}
答案 0 :(得分:1)
首先,对不起,这将是非常冗长的。我写完这篇文章是因为我查看了你的代码并试图理解它(顺便说一下,这是不成功的)。首先,我会告诉你我认为问题所在:
首先得出简短的结论:
for (int a = 0; a < fieldArray[1].varName.Length; a++)
{
parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
// ^^^
// this might be the problem.
}
我怀疑a
总是从0
到2
,而join
可能是只有1个元素的数组,即。唯一有效的索引是0
。这是由于方法populateLabelTxtBox
中的分配:
fieldArray[a].join = new int[]{strNumber};
// ^^^^^^^^^^^
// only one element in 'fieldArray[i].join'
现在进行长时间的演练:
请原谅我首先说你的代码有很多问题,但我会集中精力研究你提出的问题。
让我们看一下for
事件处理程序中的Save_Click
循环,我怀疑IndexOutOfRangeException
被抛出:
for (int a = 0; a < fieldArray[1].varName.Length; a++)
{
parts[fieldArray[a].join[a]] = fieldArray[a].txtBox.Text;
}
错误可能是由不同的数组访问引起的。我查看了所有这些数组的定义和赋值 - 为什么你需要这么多的数组,顺便说一下。 - 检查他们的界限。
fieldArray
似乎有100件商品。fieldArray[i].varName
似乎有3个项目。fieldArray[i].join
类中的初始化代码做出判断,Field
似乎也有3个项目。 (但这会变得更糟糕;但请暂时忍受我。)由于提出了第二点,我现在假设您的for
循环计数器a
从0
运行到2
。这意味着:
fieldArray[a]
可能没问题,因为fieldArray
可以容纳100件物品而且我们只看前3件。fieldArray[a].join[a]
也应该没问题,因为它应该有3个项目,我们正在查看所有这些项目。但是,目前尚不清楚parts[...]
是否为有效的数组访问;这取决于两件事:
parts
中的项目数,具体取决于您的输入文本文件; fieldArray[a].join[a]
的值,用作parts
的索引。 fieldArray[a].join[a]
必须介于0
和输入文本文件中的项目数之间;那么让我们看一下join
实际填充的方式。这似乎发生在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];
}
(到现在为止,我感觉我可以永远追逐数组和数组索引。因此,我强烈建议您重新考虑代码设计,以便更容易理解和维护。)
有两件事似乎令人怀疑:
strNumber = strNumber + 1;
(我必须承认我不太了解你的代码,看看你在这里做了什么,所以让我们跳过它。)
fieldArray[a].join =
的 new int[]{strNumber};
强>
这意味着fieldArray[a].join
现在是一个数组,而不是3,但只有1项!如果您现在回头看Save_Click
循环:
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]
不再可能有效,因为a
可能是0
和2
之间的任意数字,而join
只允许索引0
}。
我不确定我的一切是否正确,但我已经向您展示了通过代码查找错误的方法。我还证明了您的代码在某些方面存在误导性,例如:您将数组初始化为某个容量,以后实际上会更改为其他内容。
我希望这对你有所帮助。