[英]DataGridView - cell validation - prevent CurrentRow/Cell change
I have WinForms DataGridView
with source set to SortableBindingList
. 我有WinForms
DataGridView
,其源设置为SortableBindingList
。 In this form, there's column Comment
and I need to prevent user from inserting some characters, thus validation. 在此表单中,有
Comment
)列,我需要防止用户插入某些字符,从而进行验证。
What I want to do is, whenever user enters invalid value, system will notify him ( OnNotification( 'You entered wrong comment');
) and force him/her to stay in edit mode. 我想做的是,每当用户输入无效值时,系统都会通知他(
OnNotification( 'You entered wrong comment');
)并强迫他/她保持编辑模式。
So far I build solution like this: 到目前为止,我建立了这样的解决方案:
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;
}
}
}
I have following issues with this: 我对此有以下问题:
OnCellValidating
is triggered only when whole form is closing or when current row is changed, not after I finish editing of single cell , so I've put check into CellEndEdit
. OnCellValidating
,而不是在我完成单个单元格的编辑之后才触发,因此我将检查置于CellEndEdit
。 Enter
/ Esc
to end editing, it works as expected and desired. Enter
/ Esc
结束编辑时,它可以按预期和期望的方式工作。 Enter
(displays notification on invalid comment) and then Esc
(to cancel edit) it uses value pushed by Enter
(because edit mode has finished). Enter
(在无效评论上显示通知),然后使用Esc
(取消编辑)时,它将使用Enter
推入的值(因为编辑模式已完成)。 So my questions are : 所以我的问题是 :
CellValidating
after each cell edit, not when form is closing CellValidating
,而不是在窗体关闭时触发 CurrentRow
and CurrentCell
change even after mouse click? CurrentRow
和CurrentCell
更改? When I use mouse and click to another row, cell stays in edit mode, but another row gets selected.
当我使用鼠标并单击到另一行时,单元格保持在编辑模式,但是另一行被选中。
Here I would use a global Boolean, bool isInvalidState
say and a global DataGridViewCell = invalidCell
object. 在这里,我将使用全局布尔值,
bool isInvalidState
说和全局DataGridViewCell = invalidCell
对象。 In the default state you can set isInvalidState = false
and invalidCell = null
. 在默认状态下,可以设置
isInvalidState = false
和invalidCell = null
。 Then using 然后使用
private bool OnNotification(string cellValue)
{
// Check for error.
if (error)
return false;
}
Then in the above method 然后在上面的方法
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;
}
}
}
Now, wire-up an event CellContentClick
on your DataGridView
and check if isInvalidState == true
现在,在
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.
}
When I try to use Enter (displays notification on invalid comment) and then Esc (to cancel edit) it uses value pushed by Enter (because edit mode has finished).
当我尝试使用Enter(在无效评论上显示通知),然后使用Esc(取消编辑)时,它将使用Enter推入的值(因为编辑模式已完成)。
I am not sure about this problem; 我不确定这个问题。 it is likely you will have to handle the
KeyDown
event and capture the escape key - handling it differently. 您可能必须处理
KeyDown
事件并捕获转义键-以不同的方式处理它。
I hope this helps. 我希望这有帮助。
Try something like this. 尝试这样的事情。 It shall work.
它会工作。
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;
}
}
Unfortunately, MoonKnight's solution didn't work fully for me as the code in CellContentClick
event handler never set the control back to the cell that was being validated for its value, when it had an invalid value. 不幸的是,MoonKnight的解决方案对我而言并不完全有效,因为
CellContentClick
事件处理程序中的代码从未将控件设置回被验证为其值有效的单元格(当它具有无效值时)。 Nevertheless, considering his valuable hint of using global variables isInvalidState
and invalidCell
helped me constructing the following solution that works exactly as asked in the OP. 尽管如此,考虑到他使用全局变量
isInvalidState
和invalidCell
宝贵提示,它帮助我构建了以下解决方案,该解决方案完全符合OP中的要求。
Using the combination of CellValidating
and CellValidated
in the right way solves the problem as follows: 正确使用
CellValidating
和CellValidated
的组合可解决以下问题:
Do your data validation inside the CellValidating
event handler. 在
CellValidating
事件处理程序中进行数据验证。 Set the isInvalidState
flag and the cellWithInvalidUserInput
variable (NOTE: I renamed the invalidCell
to cellWithInvalidUserInput
): 设置
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;
}
}
The data validation function: 数据验证功能:
bool isInvalidState;
DataGridViewCell cellWithInvalidUserInput;
private bool ValidateCurrentCellValue(DataGridViewCell cellToBeValidated)
{
//return 'true' if valid, 'false' otherwise
}
Perform desired actions on UI controls inside the CellValidated
event handler: 在
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.