DataGridView 从更新中跳过列
DataGridView skip Column from Updating
是否可以跳过或删除更新到数据库的 DataGridView
的特定列?
我需要防止列更新到数据库,因为列值是加密的,当我解密时,解密的值更新到数据库。
我以前用过这段代码,但这确实减慢了网格速度。
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (hide == false && e.ColumnIndex == 2 && e.RowIndex != this.dataGridView1.NewRowIndex)
{
e.Value = Decrypt(e.Value.ToString());
}
}
使用此代码更新值:
private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
{
DataTable changes = ((DataTable)dataGridView1.DataSource).GetChanges();
if (changes != null)
{
MySqlCommandBuilder mcb = new MySqlCommandBuilder(mySqlDataAdapter);
((DataTable)dataGridView1.DataSource).AcceptChanges();
mySqlDataAdapter.UpdateCommand = mcb.GetUpdateCommand();
mySqlDataAdapter.Update(changes);
}
}
根据标题所说,将列的 ReadOnly
属性 设置为 true 就足够了,但是由于您想在网格中显示列的解密值,以防止列不在数据库中更新,您可以使用以下任一选项:
- 在列本身中显示加密值并将更新命令更改为不包含更新该特定列的语句。
- 您可以在另一个未绑定的列中显示加密值。
在这个 post 中,我将向您展示第二种解决方案的示例。
我想你有一个 string Decrypt(string value)
方法来解密加密的字符串。我也可以让你有一个包含加密值的列 "A" 并且作为问题你想在网格的 "B" 列中显示解密值。
因此请执行以下步骤:
- 将 "A" 列的
Visible
属性 设置为 false
。
- 添加一个
DataGridViewTextBox
列并将其名称设置为 "B"
- 处理
DtaGridView
的 CellFormatting
事件,如下所示:
private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if(e.ColumnIndex<0 || e.RowIndex<0)
return;
var columnB = grid.Columns[e.ColumnIndex];
if (columnB.Name != "B")
return;
var value = grid.Rows[e.RowIndex].Cells["A"].Value;
if (value == null || value == DBNull.Value)
return;
cell.Value = Decrypt(value.ToString());
}
备注
- 离开行后保存更改不是个好主意。最好在编辑完成后通过单击“保存”按钮来保存更改。
- 您不需要致电
AcceptChanges
。事实上你不应该!
通常设置 cell.Value = Decrypt(value.ToString());
就足够了,但是由于 Decrypt
可能会遇到性能问题,而不是设置 e.Value
你可以检查单元格是否没有'没有值,将为单元格设置值:
var cell = grid.Rows[e.RowIndex].Cells["B"];
if (cell.Value== null || cell.Value == DBNull.Value)
{
cell.Value = Decrypt(value.ToString());
}
- 请注意里面的警告
CellFormatting
事件的备注部分:每次绘制每个单元格时都会发生 CellFormatting
事件,因此
处理此事件时应避免冗长的处理。
是否可以跳过或删除更新到数据库的 DataGridView
的特定列?
我需要防止列更新到数据库,因为列值是加密的,当我解密时,解密的值更新到数据库。
我以前用过这段代码,但这确实减慢了网格速度。
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (hide == false && e.ColumnIndex == 2 && e.RowIndex != this.dataGridView1.NewRowIndex)
{
e.Value = Decrypt(e.Value.ToString());
}
}
使用此代码更新值:
private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
{
DataTable changes = ((DataTable)dataGridView1.DataSource).GetChanges();
if (changes != null)
{
MySqlCommandBuilder mcb = new MySqlCommandBuilder(mySqlDataAdapter);
((DataTable)dataGridView1.DataSource).AcceptChanges();
mySqlDataAdapter.UpdateCommand = mcb.GetUpdateCommand();
mySqlDataAdapter.Update(changes);
}
}
根据标题所说,将列的 ReadOnly
属性 设置为 true 就足够了,但是由于您想在网格中显示列的解密值,以防止列不在数据库中更新,您可以使用以下任一选项:
- 在列本身中显示加密值并将更新命令更改为不包含更新该特定列的语句。
- 您可以在另一个未绑定的列中显示加密值。
在这个 post 中,我将向您展示第二种解决方案的示例。
我想你有一个 string Decrypt(string value)
方法来解密加密的字符串。我也可以让你有一个包含加密值的列 "A" 并且作为问题你想在网格的 "B" 列中显示解密值。
因此请执行以下步骤:
- 将 "A" 列的
Visible
属性 设置为false
。 - 添加一个
DataGridViewTextBox
列并将其名称设置为 "B" - 处理
DtaGridView
的CellFormatting
事件,如下所示:
private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if(e.ColumnIndex<0 || e.RowIndex<0)
return;
var columnB = grid.Columns[e.ColumnIndex];
if (columnB.Name != "B")
return;
var value = grid.Rows[e.RowIndex].Cells["A"].Value;
if (value == null || value == DBNull.Value)
return;
cell.Value = Decrypt(value.ToString());
}
备注
- 离开行后保存更改不是个好主意。最好在编辑完成后通过单击“保存”按钮来保存更改。
- 您不需要致电
AcceptChanges
。事实上你不应该! 通常设置
cell.Value = Decrypt(value.ToString());
就足够了,但是由于Decrypt
可能会遇到性能问题,而不是设置e.Value
你可以检查单元格是否没有'没有值,将为单元格设置值:var cell = grid.Rows[e.RowIndex].Cells["B"]; if (cell.Value== null || cell.Value == DBNull.Value) { cell.Value = Decrypt(value.ToString()); }
- 请注意里面的警告
CellFormatting
事件的备注部分:每次绘制每个单元格时都会发生CellFormatting
事件,因此 处理此事件时应避免冗长的处理。