DataGridView -单元格验证-防止当前值/单元格更改
本文关键字:单元格 验证 DataGridView | 更新日期: 2023-09-27 18:08:28
我有WinForms DataGridView
与源设置为SortableBindingList
。在这个表单中,有列Comment
,我需要防止用户插入一些字符,从而验证。
我想做的是,每当用户输入无效的值时,系统将通知他(OnNotification( 'You entered wrong comment');
)并强制他/她保持编辑模式
到目前为止,我构建了这样的解决方案:
void MyDataGridView_CellEndEdit( object sender, DataGridViewCellEventArgs e )
{
if (e.ColumnIndex == ColumnComment.Index) {
object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if( (data != null) && (!CommentIsValid( data.ToString()))){
CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
BeginEdit( true );
// My notification method
OnNotification( String.Format( "Comment `{0}` contains invalid characters) );
return;
}
}
}
我有以下问题:
-
OnCellValidating
仅在整个表单关闭或当前行更改时触发,而不是在我完成单个单元格编辑后触发,因此我已将检查放入CellEndEdit
。 - 当我使用
Enter
/Esc
结束编辑时,它按预期工作。 - 当我使用鼠标并单击另一行时,单元格保持在编辑模式,但另一行被选中。
- 当我尝试使用
Enter
(显示无效评论通知),然后Esc
(取消编辑),它使用Enter
(因为编辑模式已经完成)推值。
所以我的问题是:
- 我如何在每个单元格编辑后触发
CellValidating
,而不是当窗体关闭 - 鼠标点击后,如何防止
CurrentRow
和CurrentCell
发生变化? - 如何强制单元格在编辑模式下保持 ?
当我使用鼠标并单击另一行时,单元格保持在编辑模式,但另一行被选中。
这里我将使用一个全局布尔值,bool isInvalidState
和一个全局DataGridViewCell = invalidCell
对象。默认情况下,可以设置"isInvalidState = false
"answers"invalidCell = null
"。然后使用
private bool OnNotification(string cellValue)
{
// Check for error.
if (error)
return false;
}
然后在上面的方法
void MyDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == ColumnComment.Index) {
object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if((data != null) && (!CommentIsValid(data.ToString()))){
CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
BeginEdit(true);
// My notification method
isInvalidState = OnNotification(
String.Format("Comment `{0}` contains invalid characters));
if (isInvalidState)
invalidCell = MyDataGridView[e.RowIndex, e.ColumnIndex];
return;
}
}
}
现在,在你的DataGridView
上连接一个事件CellContentClick
,并检查isInvalidState == true
是否
private void MyDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (isInvlaidState)
{
isInvalidState = false;
MyDataGridView.CurrentCell = invalidCell;
invalidCell = null;
return;
}
// Do other stuff here.
}
当我尝试使用Enter(显示无效评论的通知),然后Esc(取消编辑),它使用回车推的值(因为编辑模式已经完成)。
我对这个问题不确定;您很可能必须处理KeyDown
事件并捕获转义键——以不同的方式处理。
试试这样做。它会工作的。
private void datagridview1_dataGridview_CellValidating
(object sender, DataGridViewCellValidatingEventArgs e)
{
if (datagridview1_dataGridview.Rows[e.RowIndex].Cells[2].Value.Equals(""))
{
MessageBox.Show("Product name should not be empty", "Error");
datagridview1_dataGridview.CurrentCell = datagridview1_dataGridview.Rows[e.RowIndex].Cells[2];
datagridview1_dataGridview.CurrentCell.Selected = true;
}
}
不幸的是,MoonKnight的解决方案并没有完全为我工作,因为CellContentClick
事件处理程序中的代码从未将控件设置回正在验证其值的单元格,当它具有无效值时。然而,考虑到他使用全局变量isInvalidState
和invalidCell
的有价值的提示,帮助我构建了以下解决方案,它完全按照op中的要求工作。
正确使用CellValidating
和CellValidated
的组合可以解决如下问题:
在CellValidating
事件处理程序中执行数据验证。设置isInvalidState
标志和cellWithInvalidUserInput
变量(注意:我将invalidCell
重命名为cellWithInvalidUserInput
):
private void MyDataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
var cellUnderConsideration = MyDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (!ValidateCurrentCellValue(cellUnderConsideration))
{
OnNotification( String.Format( "Comment `{0}` contains invalid characters) );
//Or MessageBox.Show("your custom message");
isInvalidState = true;
cellWithInvalidUserInput = cellUnderConsideration;
e.Cancel = true;
}
}
数据验证函数:
bool isInvalidState;
DataGridViewCell cellWithInvalidUserInput;
private bool ValidateCurrentCellValue(DataGridViewCell cellToBeValidated)
{
//return 'true' if valid, 'false' otherwise
}
在CellValidated
事件处理程序中的UI控件上执行所需的操作:
private void MyDataGridView_CellValidated(object sender, DataGridViewCellEventArgs e)
{
if (isInvalidState)
{
isInvalidState = false;
if (cellWithInvalidUserInput != null && cellWithInvalidUserInput.RowIndex > -1)
{
MyDataGridView.CurrentCell = cellWithInvalidUserInput;
MyDataGridView.CurrentCell.Selected = true;
MyDataGridView.BeginEdit(true);
}
cellWithInvalidUserInput = null;
}
}