峰峦@叠嶂 2025-06-04 15:13 采纳率: 98.4%
浏览 5
已结题

直接修改查询datagridview的查询结果

您好,请教一下,我们从库存表MaterialStock的查询内容,想直接在datagridview内修改保存,查询结果包含这几列-- "MaterialID", "MaterialName", "BatchNumber","TotalQuantity","Remaining","EntryDate",另外, BatchID是我们数据表内自增长的ID列,没有体现在查询结果内,以下是示例代码,请帮我完善一下,实现上述目标,谢谢;


  private readonly List<string> AllowedColumns = new List<string>
  {
      "MaterialID", "MaterialName", "BatchNumber","TotalQuantity","Remaining","EntryDate"
  };
  private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
  {
      if (e.RowIndex < 0 || dataGridView1.Rows[e.RowIndex].IsNewRow) return;

      try
      {
          string columnName = dataGridView1.Columns[e.ColumnIndex].Name;

          // 验证列名是否允许编辑
          if (!AllowedColumns.Contains(columnName))
          {
              MessageBox.Show("不允许编辑此列!");
              dataGridView1.CancelEdit();
              return;
          }

          using (var conn = new SqlConnection(connectionString))
          {
              conn.Open();

              // 获取修改后的值
              var row = dataGridView1.Rows[e.RowIndex];
              object cellValue = row.Cells[e.ColumnIndex].Value;
              int BatchId = Convert.ToInt32(row.Cells["BatchID"].Value);

              // 更新数据库
              using (var cmd = new SqlCommand(
                  @"UPDATE MaterialStock 
            SET " + columnName + @" = @CellValue
            WHERE BatchID = @",
                  conn))
              {
                  // 使用参数化查询防止SQL注入
                  cmd.Parameters.AddWithValue("@CellValue", cellValue ?? DBNull.Value);
                  cmd.Parameters.AddWithValue("@BatchID", BatchId);

                  int rowsAffected = cmd.ExecuteNonQuery();
                  if (rowsAffected == 0)
                  {
                      throw new Exception("数据已被其他用户修改,请刷新后重试!");
                  }
              }
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show($"更新失败:{ex.Message}");
          dataGridView1.CancelEdit(); // 撤销单元格修改
      }

  }
  • 写回答

6条回答 默认 最新

  • 阿里嘎多学长 2025-06-04 15:13
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    解决方案

    你可以使用 DataGridViewEditing 事件来实现直接修改查询结果。下面是一个简单的示例代码:

    private void dataGridView1_CellEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.ColumnIndex == 0) // MaterialID
        {
            TextBox tb = e.Control as TextBox;
            tb.ReadOnly = true;
        }
        else if (e.ColumnIndex == 1) // MaterialName
        {
            TextBox tb = e.Control as TextBox;
            tb.ReadOnly = false;
        }
        else if (e.ColumnIndex == 2) // B
        {
            TextBox tb = e.Control as TextBox;
            tb.ReadOnly = false;
        }
    }
    
    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 1) // MaterialName
        {
            // 保存修改后的 MaterialName
            MaterialStock materialStock = dataGridView1.Rows[e.RowIndex].DataBoundItem as MaterialStock;
            materialStock.MaterialName = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
        }
        else if (e.ColumnIndex == 2) // B
        {
            // 保存修改后的 B
            MaterialStock materialStock = dataGridView1.Rows[e.RowIndex].DataBoundItem as MaterialStock;
            materialStock.B = Convert.ToDouble(dataGridView1.Rows[e.RowIndex].Cells[2].Value);
        }
    }
    

    CellEditingControlShowing 事件中,我们可以根据当前编辑的列来设置对应的文本框是否可读写。

    CellEndEdit 事件中,我们可以获取当前编辑的行和列,然后根据列的索引来保存修改后的值。

    请注意,这只是一个简单的示例代码,你可能需要根据你的实际情况进行修改。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 6月25日
  • 已采纳回答 6月17日
  • 创建了问题 6月4日