动态添加的DataGridView没有提交要求的结果

Dynamic added DataGridView not submitting the required result

我在这里尝试创建一个动态数据网格。这将作为文本框中输入的文本的自动完成。当我在文本框中键入内容时,它将搜索数据库并在动态数据网格中显示匹配的值,当我按下回车键时,它将在可用的文本框中显示选定的记录。

但我面临的问题是,当我按回车键时,我收到一条错误消息,“索引超出范围。必须是非负数且小于集合的大小。”

下面粘贴我写的代码

有人请检查并告诉我可能的错误。

private void Form1_Load(object sender, EventArgs e)
        {
            Search();

        }


        private DataGridView dgview;
        private DataGridViewTextBoxColumn dgviewcol1;
        private DataGridViewTextBoxColumn dgviewcol2;

        void Search()
        {
            dgview = new DataGridView();
            dgviewcol1 = new DataGridViewTextBoxColumn();
            dgviewcol2 = new DataGridViewTextBoxColumn();
            this.dgview.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dgview.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.dgviewcol1, this.dgviewcol2 });
            this.dgview.Name = "dgview";
            dgview.Visible = false;
            this.dgviewcol1.Visible = false;
            this.dgviewcol2.Visible = false;
            this.dgview.AllowUserToAddRows = false;
            this.dgview.RowHeadersVisible = false;
            //this.dgview.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            dgview.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            this.Controls.Add(dgview);
            this.dgview.ReadOnly = true;
            dgview.BringToFront();
        }

        void Search(int LX, int LY, int DW, int DH, string ColName, String ColSize)
        {
            this.dgview.Location = new System.Drawing.Point(LX, LY);
            this.dgview.Size = new System.Drawing.Size(DW, DH);

            string[] ClSize = ColSize.Split(',');
            //Size
            for (int i = 0; i < ClSize.Length; i++)
            {
                if (int.Parse(ClSize[i]) != 0)
                {
                    dgview.Columns[i].Width = int.Parse(ClSize[i]);
                }
                else
                {
                    dgview.Columns[i].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
                }
            }
            //Name 
            string[] ClName = ColName.Split(',');

            for (int i = 0; i < ClName.Length; i++)
            {
                this.dgview.Columns[i].HeaderText = ClName[i];
                this.dgview.Columns[i].Visible = true;
            }
        }

        bool change = true;

private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text.Length > 0)
            {
                this.dgview.Visible = true;
                dgview.BringToFront();
                Search(150, 105, 430, 200, "Product Code,Product Name", "100,0");
                //this.dgview.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.proCode_MouseDoubleClick);
                SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Gershone\source\repos\WindowsFormsApp2\db.mdf;Integrated Security=True;Connect Timeout=30");
                SqlDataAdapter sda = new SqlDataAdapter("Select Top(10) ProductName,ProductID From productdetails WHERE ProductName Like '" + textBox1.Text + "%'", con);
                DataTable dt = new DataTable();
                sda.Fill(dt);
                dgview.Rows.Clear();
                
                foreach (DataRow row in dt.Rows)
                {
                    int n = dgview.Rows.Add();
                    dgview.Rows[n].Cells[0].Value = row["ProductID"].ToString();
                    dgview.Rows[n].Cells[1].Value = row["ProductName"].ToString();
                }
            }
            else
            {
                dgview.Visible = false;
            }
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (dgview.Rows.Count > 0)
                {
                    textBox1.Text = dgview.SelectedRows[0].Cells[0].Value.ToString();
                    textBox2.Text = dgview.SelectedRows[0].Cells[1].Value.ToString();
                    this.dgview.Visible = false;
                    textBox3.Focus();
                }
                else
                {
                    this.dgview.Visible = false;

                }
            }
        }

这个错误的原因是当你执行statement

textBox1.Text = dgview.SelectedRows[0].Cells[0].Value.ToString();

textBox1_TextChanged将被触发。然后它调用 dgview.Rows.Clear();,将删除所有行。

尝试取消订阅活动 TextChanged 并重新订阅。

textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = dgview.Rows[rowIndex].Cells[0].Value.ToString();
textBox2.Text = dgview.Rows[rowIndex].Cells[1].Value.ToString();
textBox1.TextChanged += textBox1_TextChanged;

既然已经将数据保存到DataTable中,为什么不从DataTable中获取数据呢?

首先,将dt声明为全局变量。

DataTable dt; // global variable

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (textBox1.Text.Length > 0)
    {
        // ...
        SqlDataAdapter sda = new SqlDataAdapter("Select Top(10) ProductName,ProductID From productdetails WHERE ProductName Like '" + textBox1.Text + "%'", con);
        dt = new DataTable();
        sda.Fill(dt);
        // ...
    }
    // ...
}

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        if (dgview.Rows.Count > 0)
        {
            // get row index
            int rowIndex = dgview.SelectedRows[0].Index;
            textBox1.Text = dt.Rows[rowIndex][0].ToString();
            textBox2.Text = dt.Rows[rowIndex][1].ToString();
            this.dgview.Visible = false;
            textBox3.Focus();
        }
        // ...
    }
}