【问题标题】:vb.net change value of a cell in a databound datagridviewvb.net 更改数据绑定数据网格视图中单元格的值
【发布时间】:2012-10-30 11:56:46
【问题描述】:

我有一个使用 datasource 属性从数据表中填充的 datagridview。我需要在不影响数据库的情况下更改单元格的值。到目前为止,我只能发现我必须首先更改数据绑定项目,但没有关于如何做到这一点的信息。此外,我不想更改数据绑定项。

想要这样做的原因是我有一个包含开始和结束时间的记录列表,并且有一个计算字段以秒为单位给出差异。我需要改变计算域的值,并相应地改变行的高度,即每行的高度与它所代表的持续时间成正比。更改是从文本框中完成的,如果“增加”按钮被按住,该文本框会快速增加,因此我无法在每次增加时更改数据库。相反,我会经常更改表中的值,并在增量停止后更新数据库。

我已尝试使用此代码直接更新 datagridview:

dgvTasks.Rows(SelectedRowIndex).Cells(5).Value = DateAdd(DateInterval.Minute, DateDiff(DateInterval.Minute, CDate("00:00:00"), CDate(txtDuration.Text & ":00")), dgvTasks.Rows(SelectedRowIndex).Cells(4).Value)

但收到错误:

System.Data.ReadOnlyException:列 'Column1' 是只读的。

我也尝试更新数据表,并允许更新计算列:

dtblTasks.Rows(SelectedRowIndex)(5) = DateAdd(DateInterval.Minute, DateDiff(DateInterval.Minute, CDate("00:00:00"), CDate(txtDuration.Text & ":00")), dtblTasks.Rows(SelectedRowIndex)(4)) 
dgvTasks.DataSource = dtblTasks

但是计算出来的值没有变化。

我还提供了一个额外的计算值(在 SQL 中),我可以在其中找到以分钟为单位的差异,并将字符串文字附加到该值:

( CAST ( DATEDIFF(MINUTE, Tasks.TaskStart, Tasks.TaskEnd) AS NVARCHAR(10) ) + ' mins') AS TaskDurationString

有没有办法将网格与数据源分离,但仍保持数据在数据网格中可见并对其进行操作(不影响数据绑定对象)?或者也许有其他方法可以解决这个问题?

【问题讨论】:

  • 您想做出什么样的改变?在不改变底层数据源的情况下,对 datagridview 中显示的值应用转换是很容易的。无法“断开”数据源并保持数据显示在网格中。但是,您可以简化我们一个未绑定的网格并从代码中的数据表中复制值。然而,最后,最简单的方法是更新数据表 - 你为什么不能这样做?您不必将数据表的更改保存回数据库。
  • 这是我尝试使用以下命令更改单元格内容时遇到的错误:DataGridView1.Rows(1).Cells(0).Value = "test" linkdl.dropbox .com/u/60390967/LANThrax/error.jpg 我刚刚意识到,如果我尝试更改附加到单个字段的单元格的内容,它会起作用。但是,如果我尝试更改其值是其他字段组合结果的单元格,例如“(FirstName + LastName)”,则会出现该错误。
  • 不,这行不通 - DataTables 中的计算列是只读的,没有办法解决这个问题。 msdn.microsoft.com/en-us/library/ms810291.aspx 但是为什么需要计算列,为什么要更改它的值?有很多可能的途径可以解决您的问题,但仍不清楚究竟是什么问题。
  • 我有一个包含开始时间和结束时间的记录列表,计算字段是以秒为单位的差异。我需要改变计算域的值,并相应地改变行的高度,即每行的高度与它所代表的持续时间成正比。更改是从文本框中完成的,如果“增加”按钮被按住,该文本框会快速增加,因此我无法在每次增加时更改数据库。相反,我会经常更改表中的值,并在增量停止后更新数据库。我会尝试更新结束时间。
  • 更新结束时间将是可行的方法 - 然后您的计算列也会更新。当您说“因此我无法随每个增量更改数据库”时,您的意思是这就是您不直接更新数据表的原因吗?除非您愿意,否则没有理由访问数据库。如果您有一些自动触发访问数据库的事件,我建议您重新考虑该设计。

标签: vb.net datagridview


【解决方案1】:

更新DataTable 中的计算列应该可以工作 - 我刚刚尝试过,当我编辑作为计算值一部分的值之一时,以及当我更改代码中的值时,该列重新计算并更新网格 UI。

要检查的一件事是您计算的值是否正确。您应该使用DataTable~ column [Expression` 属性]1。像这样的:

dt.Columns["FullName"].Expression = "FirstName + LastName";

由于您实际上不需要将这些值中的任何一个绑定到DataTable 或将它们持久化到数据库中,因此一种可能的解决方案是在未绑定的DataGridView 计算列中完成所有这些操作。

为此,使用设计器添加一列,然后在单元格验证事件中具有如下内容:

void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
    dataGridView1.Rows[e.RowIndex].Cells["TargetColumn"].Value = dataGridView1.Rows[e.RowIndex].Cells["FirstName"].Value.ToString() + dataGridView1.Rows[e.RowIndex].Cells["LastName"].Value.ToString();
    dataGridView1.Rows[e.RowIndex].Height = dataGridView1.Rows[e.RowIndex].Cells["LastName"].Value.ToString().Length + dataGridView1.Rows[e.RowIndex].Cells["FullName"].Value.ToString().Length;
}

【讨论】:

  • 我只记得您要求使用 vb.net - 只需在此处发表评论,我会很乐意将我的代码从 c# 更新为该代码
  • 谢谢,大卫。我尝试了未绑定的 datagridview 列方法。 CellValidate 事件没有更新单元格,而其他列正在更改,因此我将计算单元格设置为以与更新其他列相同的方法进行更新。现在我只需要找到一种方法将未绑定的列设置为最左边。
  • DisplayIndex 应该为您执行此操作 - 而不是在具有要测试的 datagridview 项目的计算机上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多