【问题标题】:I can't edit a row in the datagridview我无法在 datagridview 中编辑一行
【发布时间】:2021-01-02 20:55:24
【问题描述】:

我正在尝试从 datagridview 编辑一行。每行都有一个按钮。当我按下其中一个行按钮时,会打开第二个表单,并在文本框中显示有关该行的信息,我需要编辑我想要的内容。

问题是我已经写好编辑代码了,但是无法在按钮函数中添加DataGridViewCellEventArgs,或者无法使用RowIndex来编辑特定行。

代码如下:

public void btnUpdate_Click(object sender, EventArgs e)
{
    SqlConnection conn = new SqlConnection(@"Data Source=DESKTOP-VUPD668;Initial Catalog=dbApp;Integrated Security=True");
    SqlCommand cmd;
    cmd = new SqlCommand("UPDATE tableApplication SET Name='" + txtName.Text + "',Package='" + txtPackage.Text + "',Hour='" + txtHour.Text + "',Date='" + txtDate.Text + "',Phone='" + txtPhone.Text + "',Observations='" + txtObservations.Text + "' WHERE ID=" + f1.dgvContactList.Rows[rowIndex].Cells[0].Value.ToString(), conn);
    conn.Open();

    cmd.ExecuteNonQuery();

    conn.Close();
    MessageBox.Show("Edit was saved");
    this.Close();
}

这里是带有 dgv 的主窗体中的代码

public void dgvContactList_CellContentClick(object sender, DataGridViewCellEventArgs e)
{       
    if (e.ColumnIndex == 7)
    {            
        formAddEditContact f2 = new formAddEditContact();
        int rowIndex = e.RowIndex;
        formContact f1 = new formContact();
        f2.lblTitle.Text = "Edit";
        f2.btnSave.Visible = false;
        f2.btnUpdate.Visible = true;
        
        f2.btnDelete.Visible = true;
        f2.txtName.Text = f1.dgvContactList.Rows[rowIndex].Cells[1].Value.ToString();
        f2.txtPackage.Text = f1.dgvContactList.Rows[rowIndex].Cells[2].Value.ToString();
        f2.txtHour.Text = f1.dgvContactList.Rows[rowIndex].Cells[3].Value.ToString();
        f2.txtDate.Text = f1.dgvContactList.Rows[rowIndex].Cells[4].Value.ToString();
        f2.txtPhone.Text = f1.dgvContactList.Rows[rowIndex].Cells[5].Value.ToString();
        f2.txtObservations.Text = f1.dgvContactList.Rows[rowIndex].Cells[6].Value.ToString();
        f2.ShowDialog();

如何在按钮功能中使用 RowIndex。如何添加 DataGridViewCellEventArgs。

【问题讨论】:

  • 你为什么要“创建”一个新的formContactf1?该表单从未显示,因此代码...f1.dgvContactList.Rows[rowIndex].Cells[1].Value.ToString(); 不会有任何行,因为网格尚未显示。你试过…dgvContactList.Rows[rowIndex].Cells[1].Value.ToString();
  • 您在哪里将查询结果添加到 DGV?您正在使用 cmd.ExecuteNonQuery(); 执行查询但从不获取 cmd 的结果并读取结果。
  • 以下article 可能感兴趣,请看截图。 Full source。我存根存回数据库。

标签: c# winforms


【解决方案1】:

直接访问 DataGridView 中显示的数据很少是个好主意。您应该将数据的显示方式与实际值分开。这样您就可以轻松更改显示,而无需更改使用数据的代码。

显然,您的 DataGridView 显示了一系列联系人的多个属性。每行显示一个联系人:

class Contact
{
    public int Id {get; set;}
    public string Name {get; set;}
    public DateTime BirthDay {get; set;}
    ...
}

您已将DataGridViewColumns 添加到您的DataGridView。每个 DataGridViewColumn 显示一个属性。应该显示的属性名称在DataGridViewColumn.DataPropertyName

DataGridViewColumn columnBirthDay = new DataGridViewColumn();
columnBirthDay.DataPropertyName = nameof(Contact.BirthDay);
... // set other properties.

现在您所要做的就是,获取您的数据并将它们放入 DataGridView 的 DataSource 中:

IEnumerable<Contact> contactsToDisplay = ...
this.DataGridViewContacts.DataSource = new BindingList<Contact>(contactsToDisplay);

现在,操作员编辑的每个更改都会在 DataSource 中自动更新。您的程序对数据源所做的每项更改都会自动显示出来。

以编程方式添加联系人:

BindingList<Contact> DisplayedContacts => (BindingList<Contact>)this.DataGridViewContacts.DataSource;

private void DisplayContact(Contact contact)
{
    this.DisplayedContacts.Add(contact);
}

访问已编辑的联系人,例如按下按钮后:

private void OnButtonOkClicked(object sender, ...)
{
     Collection<Contact> editedContacts = this.DisplayedContacts;
     this.ProcessEditedContacts(editedContacts);   
}

DatagridView 中的每一行都有一个按钮。如果操作员按下了您想使用该行中显示的联系人执行某项操作的按钮。

private Contact GetContact(DataGridViewRow row)
{
    return (Contact)row.DataBoundItem;
}

private void dgvContactList_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    // in baby steps:
    DataGridView dataGridView = (DataGridView)sender;
    DataGridViewRow row = dataGridView.Rows[e.RowIndex];
    Contact contact = GetContact(row);
    EditContact(contact);
}

你可以在一个大声明中做到这一点。不确定这是否会提高可读性。

private void EditContact(Contact contact)
{
    using (var dlg = new EditContactDlg())
    {
        dlg.Contact = contact;
        ... // other dialog properties

        var dialogResult = dlg.Show(this);
        if (dlgResult == DialogResult.OK)
        {
            ... // process edited contact
        }
    }
}

请注意:您将未经编辑的原始联系人附加到对话框中。如果操作员更改值并按取消,则原始联系人可能仍会更改。最好将克隆联系人附加到对话框,如果需要,使用已编辑的克隆联系人的属性来更新原始联系人。

你有没有看到,因为我没有在一个大程序中完成所有事情,所以这些程序更容易理解。它们更容易稍微改变,也可以很容易地重复使用。

例如,如果您决定不添加带有按钮的列,因为您不想在表单中显示 50 个按钮,您决定添加一个按钮来编辑“当前选定的行”,代码更改将是最小:

private void OnButtonEditCurrentRow_Clicked(object sender, ...)
{
    DataGridViewRow row = this.DataGridViewContacts.CurrentRow;
    Contact contact = GetContact(row);
    EditContact(contact);
}

如果您想添加菜单项来编辑当前行,当然也可以重复使用此过程。

由于您将联系人在 datagridview 中的显示方式与实际联系人分开,因此如果您决定以不同方式显示联系人(例如,如果您决定不再显示联系人的 ID,或如果您打算使用日语显示生日的方法。或者,如果您实现数据排序。 BindingList 始终包含内部联系人数据。

同样,如果您想更改联系人。比如把firstname和lastName分开,但还是想在一列中显示,代码改动会很小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多