在vb.net datagridview中,默認的Enter/Return鍵行爲是移動到下一行是否有一種快速而簡單的方法來避免這種情況。禁用數據網格視圖中的默認Enter/Return鍵行爲
任何建議,歡迎
在vb.net datagridview中,默認的Enter/Return鍵行爲是移動到下一行是否有一種快速而簡單的方法來避免這種情況。禁用數據網格視圖中的默認Enter/Return鍵行爲
任何建議,歡迎
你可以嘗試這樣的事情在GridView鍵按下事件
Private Sub DataGridView1_Keydown (...) Handlers DataGridView1.KeyDown
If e.KeyCode = Keys.Enter Then
' Your code here
e.SuppressKeyPress = True
End If
End Sub
另一種選擇是創建一個自定義網格視圖控制
覆蓋DataGridView(編寫自己的繼承自它),並處理OnKe yDown方法。
public partial class UserControl1 : DataGridView
{
public UserControl1()
{
InitializeComponent();
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
return;
base.OnKeyDown(e);
}
}
你可以使用按鍵事件:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//You're Code
}
e.Handled = true;
return;
}
這工作就像一個魅力。建議的簡單但唯一的解決方案,它爲我工作。 – Birk 2017-03-10 16:14:37
我自己,在DataGridView
禁用回車鍵的默認行爲時,要能夠實現以設置DataGridView.StandardTab
到true
類似的效果。啓用StandardTab
使用戶能夠更輕鬆地在表單中的不同控件之間導航。這使得它的行爲更像ListBox
,特別是如果DataGridView
只有一列。回車鍵的默認行爲以及我期望將(不存在的)DataGridView.StandardEnter
鍵設置爲true
的行爲將發送到包含控件的關鍵事件,可能導致Form.AcceptButton
被激活。 setting KeyEventArgs.SuppressKeyPress = true
in DataGridView.KeyDown
或not even firing DataGridView.KeyDown
when the input key is Enter建議的方法不啓用「標準」Enter鍵行爲;這些方法反而讓Enter鍵事件被吞噬。
下面顯示了我如何設法從DataGridView中獲得「標準」輸入關鍵行爲(包括適當調用AcceptButton
)。這是醜陋的,因爲我不知道更好的方式來運行Control.ProcessDialogKey()
(如果沒有Parent,它只是調用Parent(容器)的ProcessDialogKey()
或返回false
)中的邏輯,而不是將其複製到我自己的派生類中。 (我基本上需要使用invalid/impossible base.base.ProcessDialogKey()
syntax以更清晰的方式解決System.Windows.Forms
的不可擴展性)。因此,我不得不使用反射來訪問存在時父對象(容器)Control
對象的受保護Control.ProcessDialogKey()
方法。
DataGridVew.IsInputKey()
返回true
對於Keys.Enter
。這使得它可以看到回車鍵在其DataGridView.OnKeyDown()
方法,它最終會調用DataGridView.ProcessEnterKey()
,它基於DataGridView.EditMode
的設置以不同的方式對輸入鍵作出反應。但是,這也禁止將關鍵事件發送到ProcessDialogKey()
,從那裏正常控件將回車鍵事件吹到他們的父母(例如使AcceptButton
工作)。因此,我們通過覆蓋IsInputKey()
來恢復這種行爲,並且現在DataGridView.ProcessDialogKey()
將在按下Enter時被調用。
但這還不夠。 DataGridView.ProcessDialogKey()
對DataGridView.ProcessEnterKey()
進行了硬編碼調用,如果ProcessEnterKey()
返回false,則只調用其基址Control.ProcessDialogKey()
。在這一點上,將ProcessEnterKey()
替換爲當我們需要標準回車鍵行爲時會返回false
的東西似乎是常識。但是,唉,這是一種非虛擬方法。因此,我們被迫覆蓋一些我們可以覆蓋的東西,DataGridView.ProcessDialogKey()
,並在跳過ProcessEnterKey()
的調用時重新實現。這是我們無法直接呼叫Control.ProcessDialogKey()
的地方,並且被迫使用反射來調用父/容器對象的ProcessDialogKey()
方法。但是,一旦我們成功地打出了這個電話,我們終於有了標準的Enter行爲,即使在DataGridView
有焦點的情況下也可以使用AcceptButton
!
/// <summary>
/// A DataGridView with a StandardEnter property which behaves
/// like StandardTab.
/// </summary>
class StandardEnterDataGridView
: DataGridView
{
/// <summary>
/// Like StandardTab but for the Enter key.
/// </summary>
[Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")]
public bool StandardEnter { get; set; }
/// <summary>
/// Implement StandardEnter.
/// </summary>
protected override bool IsInputKey(Keys keyData)
{
if (StandardEnter && keyData == Keys.Enter)
// Force this key to be treated like something to pass
// to ProcessDialogKey() (like the Enter key normally
// would be for controls which aren’t DataGridView).
return false;
return base.IsInputKey(keyData);
}
private static MethodInfo _Control_ProcessDialogKey = typeof(Control).GetMethod("ProcessDialogKey", BindingFlags.Instance|BindingFlags.NonPublic);
protected override bool ProcessDialogKey(Keys keyData)
{
if (StandardEnter && keyData == Keys.Enter)
// Copy the default implementation of
// Control.ProcessDialogKey(). Since we can’t access
// the base class (DataGridView)’s base class’s
// implementation directly, and since we cannot
// legally access Control.ProcessDialogKey() on other
// Control object, we are forced to use reflection.
return Parent == null ? false : (bool)_Control_ProcessDialogKey.Invoke(Parent, new object[] {keyData, });
return base.ProcessDialogKey(keyData);
}
}
我只是將我的Gride的聲明更改爲這個新類,但沒有任何反應,ENTER KEY仍會進入下一行: -/ this.dbGride = new StandardEnterDataGridView(); – duardbr 2016-03-15 19:43:46
@duardbr我在很長一段時間沒有看過這段代碼,但考慮到你在你的評論中寫了'this.dbGride = new StandardEnterDataGridView();',你是否記得將'StandardEnter'屬性設置爲'true' ?也許'this.dbGride = new StandardEnterDataGridView {StandardEnter = true,};'。或者,如果您使用VS Designer,請嘗試在Designer的屬性網格視圖中啓用'StandardEnter'屬性。 – binki 2016-03-15 19:49:30
感謝您的回覆,是的,StandardEnter是真實的,沒有任何反應 – duardbr 2016-03-16 13:30:25
接受的解決方案對我無效。 DID下面的代碼。從http://www.vbforums.com/showthread.php?603242-Block-enter-key-in-datagridview-in-vb-net:(原始來源未知)
Public Class clsDataGridView
Inherits System.Windows.Forms.DataGridView
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
If keyData = Keys.Return Or keyData = Keys.Tab Then
If CurrentCellAddress.X = ColumnCount - 1 Then
keyData = Keys.Cancel
With msg
.WParam = CType(Keys.Cancel, IntPtr)
End With
Else
keyData = Keys.Tab
With msg
.WParam = CType(Keys.Tab, IntPtr)
End With
End If
End If
If keyData = (Keys.Shift Or Keys.Tab) Then
If CurrentCellAddress.X = 0 Then
keyData = Keys.Cancel
With msg
.WParam = CType(Keys.Cancel, IntPtr)
End With
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
If keyData = Keys.Return Or keyData = Keys.Tab Then
If CurrentCellAddress.X = ColumnCount - 1 Then
keyData = Keys.Cancel
Else
keyData = Keys.Tab
End If
End If
If keyData = (Keys.Shift Or Keys.Tab) Then
If CurrentCellAddress.X = 0 Then
keyData = Keys.Cancel
End If
End If
Return MyBase.ProcessDialogKey(keyData)
End Function
End Class
它是這樣工作的魅力 – Ramji 2009-12-11 14:30:53
+1這正是我需要的。謝謝 – gyurisc 2010-03-04 09:28:48
一旦涉及到e.suppressKeyPress = true,應用程序就會終止。 – Kenta 2014-01-17 04:41:06