【问题标题】:C# / Winforms: Copy string from a textbox to an existing arrayC# / Winforms:将字符串从文本框复制到现有数组
【发布时间】:2011-03-25 07:27:59
【问题描述】:

嘿!我正在尝试将一些数据从文本框中放入现有数组。

基本上当我双击一个节点时,程序会将文本文件中的信息拆分为数组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];

    }

}
}

【问题讨论】:

  • 我真的不清楚该循环的真正含义。 fieldArray[1].varName.Length有什么意义?是否可以保证fieldArray 的长度相同,或者fieldArray[a].join[a] 有效? parts的长度和fieldArray[1].varName.Length相比呢?
  • 您还需要告诉我们您在哪里拆分了行。我们需要查看每个 fieldArray 和 join item 是如何填充的。你能编辑你的问题并包括这个吗?
  • 在该链接的代码开头这意味着什么?私有字段 [] 字段数组 = 新字段 [100];可能是Index的可能原因超出了数组错误的范围吗?
  • 我包含了完整的代码。 private void populateLabelTxtBox(string path) 显示我拆分的部分。加入项目位于私有 void Save_Click(object sender, EventArgs e)。 @EmreVeriyaz private Field[] fieldArray = new Field[100];是创建一个字段数组@Jon Skeet,fieldArray[1].varName.Length 是我正在搜索的变量数量的长度。 fieldArray 是包含 100 个字段的数组的名称。 fieldArray[a]join[a] 是一个包含 100 个字段的数组,包含为parts[] 数组提取数据的数字。部分[]的长度取决于选择的文件。
  • @New27 我的意思是 100 可能不足以满足您的代码需求。

标签: c# winforms textbox


【解决方案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'

现在是一个漫长的演练:

请原谅我首先说您的代码有很多问题,但我会尽量专注于您所询问的问题。

让我们看看Save_Click 事件处理程序中的for 循环,我怀疑在其中抛出了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 似乎也有 3 项,如果我根据 Field 类中的初始化代码来判断的话。 (但这会证明是错误的;但请暂时容忍我。)

由于第二点,我现在假设您的for 循环计数器a0 运行到2。这意味着:

  • fieldArray[a] 可能没问题,因为 fieldArray 有 100 件物品的空间,我们只看前 3 件。
  • fieldArray[a].join[a] 也应该没问题,因为它应该正好有 3 个项目,我们正在查看所有项目。

但是,不清楚parts[...]是否是有效的数组访问;这取决于两件事:

  1. parts 中的项目数,取决于您输入的文本文件;
  2. 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 可能是介于02 之间的任何数字,而join 只允许索引0


我不确定我是否一切正确,但我已经向您展示了一种通过代码查找错误的方法。我还表明您的代码在某些方面具有误导性,例如您将数组初始化为一定的容量,稍后实际上会更改为其他内容。

希望这一切对你有所帮助。

【讨论】:

    猜你喜欢
    • 2015-03-23
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 2016-01-22
    • 2016-01-05
    • 1970-01-01
    相关资源
    最近更新 更多