I'm using a DataGridView in my WinForms application. My main objective is to make the Enter key not move to the next row in the grid. I still want the enter key to validate and end edit mode.
我在WinForms应用程序中使用DataGridView。我的主要目标是使Enter键不移动到网格中的下一行。我仍然希望输入密钥验证并结束编辑模式。
I found this FAQ entry and subclassed DataGridView to override ProcessDialogKey(). If the key pressed is Enter, I call EndEdit(), otherwise I call base.ProcessDialogKey().
我发现这个FAQ条目和子类DataGridView重写ProcessDialogKey()。如果按下的键是Enter,我调用EndEdit(),否则我调用base.ProcessDialogKey()。
It works great, except the CellValidating event isn't fired.
它工作得很好,除了没有触发CellValidating事件。
Currently, I'm just manually calling my validation logic before I call EndEdit, but it seems like I'm missing something.
目前,我只是在调用EndEdit之前手动调用我的验证逻辑,但似乎我错过了一些东西。
I guess I could call OnCellValidating, but then I'd be worried I'm missing some other event. What I really want is some flavour of EndEdit() that behaves just like pressing enter on the last row of a grid with adding disabled.
我想我可以打电话给OnCellValidating,但后来我担心我错过了其他一些事件。我真正想要的是一些EndEdit()的行为,就像在网格的最后一行按Enter键并添加禁用一样。
5 个解决方案
#1
CellValidating doesn't get called until you change the CurrentCell. So the way I kludged around this was to change the CurrentCell, then switch back to the current one.
在更改CurrentCell之前,不会调用CellValidating。所以我解决这个问题的方法是更改CurrentCell,然后切换回当前的。
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
DataGridViewCell currentCell = CurrentCell;
EndEdit();
CurrentCell = null;
CurrentCell = currentCell;
return true;
}
return base.ProcessDialogKey(keyData);
}
#2
JJO's code will crash if cell is in edit mode. Below avoids validation exception:
如果单元格处于编辑模式,JJO的代码将崩溃。以下避免了验证异常:
DataGridViewCell currentCell = AttachedGrid.CurrentCell;
try
{
AttachedGrid.EndEdit();
AttachedGrid.CurrentCell = null;
AttachedGrid.CurrentCell = currentCell;
}
catch
{
AttachedGrid.CurrentCell = currentCell;
AttachedGrid.CurrentCell.Selected = true;
}
Source: Kennet Harris's answer here
资料来源:Kennet Harris的回答
#3
if your DataGridView's DataSource is BindingSouce, do this (put this in your Key processing events):
如果您的DataGridView的DataSource是BindingSouce,请执行此操作(将此项放入您的Key处理事件中):
bds.EndEdit();
if your DataGridView's DataSource is DataTable:
如果您的DataGridView的DataSource是DataTable:
this.BindingContext[dgv.DataSource].EndCurrentEdit();
#4
thanks for the solution. my version is a slight different from yours, because when i move to the other cell, and my code returns e.cancel=false in the cell validating event, an error will be generated, says that: "operation did not succeed, because the program cannot commit or quit a cell value change". so i put try catch to overcome this problem.
谢谢你的解决方案。我的版本与你的版本略有不同,因为当我移动到另一个单元格,并且我的代码在单元格验证事件中返回e.cancel = false时,会产生错误,说:“操作没有成功,因为程序无法提交或退出单元格值更改“。所以我把try catch来克服这个问题。
this is my code:
这是我的代码:
Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Dim key As Keys = (keyData And Keys.KeyCode)
If key = Keys.Enter Then
If MyBase.CurrentCell.ColumnIndex = 1 Then
Dim iRow As Integer = MyBase.CurrentCell.RowIndex
MyBase.EndEdit()
Try
MyBase.CurrentCell = Nothing
MyBase.CurrentCell = MyBase.Rows(iRow).Cells(1)
frmFilter.cmdOk_Click(Me, New EventArgs)
Catch ex As Exception
End Try
Return True
End If
End If
Return MyBase.ProcessDialogKey(keyData)
End Function
#5
No, but you can manually fire the CellValidating event. Just create the proper parameters. All events are is a class using the Observer Pattern, they're no different than any other method. If that doesn't work, you can create a KeyPress event on the cell and emulate pressing Enter on the cell, but that may mess with the users UI, just put the carat back where it was.
不,但您可以手动触发CellValidating事件。只需创建适当的参数。所有事件都是使用观察者模式的类,它们与任何其他方法没有什么不同。如果这不起作用,您可以在单元格上创建一个KeyPress事件并模拟单元格上的Enter键,但这可能会弄乱用户UI,只需将克拉放回原处。
#1
CellValidating doesn't get called until you change the CurrentCell. So the way I kludged around this was to change the CurrentCell, then switch back to the current one.
在更改CurrentCell之前,不会调用CellValidating。所以我解决这个问题的方法是更改CurrentCell,然后切换回当前的。
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
DataGridViewCell currentCell = CurrentCell;
EndEdit();
CurrentCell = null;
CurrentCell = currentCell;
return true;
}
return base.ProcessDialogKey(keyData);
}
#2
JJO's code will crash if cell is in edit mode. Below avoids validation exception:
如果单元格处于编辑模式,JJO的代码将崩溃。以下避免了验证异常:
DataGridViewCell currentCell = AttachedGrid.CurrentCell;
try
{
AttachedGrid.EndEdit();
AttachedGrid.CurrentCell = null;
AttachedGrid.CurrentCell = currentCell;
}
catch
{
AttachedGrid.CurrentCell = currentCell;
AttachedGrid.CurrentCell.Selected = true;
}
Source: Kennet Harris's answer here
资料来源:Kennet Harris的回答
#3
if your DataGridView's DataSource is BindingSouce, do this (put this in your Key processing events):
如果您的DataGridView的DataSource是BindingSouce,请执行此操作(将此项放入您的Key处理事件中):
bds.EndEdit();
if your DataGridView's DataSource is DataTable:
如果您的DataGridView的DataSource是DataTable:
this.BindingContext[dgv.DataSource].EndCurrentEdit();
#4
thanks for the solution. my version is a slight different from yours, because when i move to the other cell, and my code returns e.cancel=false in the cell validating event, an error will be generated, says that: "operation did not succeed, because the program cannot commit or quit a cell value change". so i put try catch to overcome this problem.
谢谢你的解决方案。我的版本与你的版本略有不同,因为当我移动到另一个单元格,并且我的代码在单元格验证事件中返回e.cancel = false时,会产生错误,说:“操作没有成功,因为程序无法提交或退出单元格值更改“。所以我把try catch来克服这个问题。
this is my code:
这是我的代码:
Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Dim key As Keys = (keyData And Keys.KeyCode)
If key = Keys.Enter Then
If MyBase.CurrentCell.ColumnIndex = 1 Then
Dim iRow As Integer = MyBase.CurrentCell.RowIndex
MyBase.EndEdit()
Try
MyBase.CurrentCell = Nothing
MyBase.CurrentCell = MyBase.Rows(iRow).Cells(1)
frmFilter.cmdOk_Click(Me, New EventArgs)
Catch ex As Exception
End Try
Return True
End If
End If
Return MyBase.ProcessDialogKey(keyData)
End Function
#5
No, but you can manually fire the CellValidating event. Just create the proper parameters. All events are is a class using the Observer Pattern, they're no different than any other method. If that doesn't work, you can create a KeyPress event on the cell and emulate pressing Enter on the cell, but that may mess with the users UI, just put the carat back where it was.
不,但您可以手动触发CellValidating事件。只需创建适当的参数。所有事件都是使用观察者模式的类,它们与任何其他方法没有什么不同。如果这不起作用,您可以在单元格上创建一个KeyPress事件并模拟单元格上的Enter键,但这可能会弄乱用户UI,只需将克拉放回原处。