C# 如何防止在编辑DataGridViewTextBoxColumn并按Enter键后转到下一行?
我正在使用C# 如何防止在编辑DataGridViewTextBoxColumn并按Enter键后转到下一行?,c#,datagridview,focus,keypress,datagridviewtextboxcell,C#,Datagridview,Focus,Keypress,Datagridviewtextboxcell,我正在使用DataGridViews开发一个程序。 在一个DatagridView中有一个DataGridViewTextBoxColumn,用户可以编辑该列。当用户输入完数字后,按键盘上的ENTER键。现在,DataGridView执行所有的事件,在所有事件之后,最后一件事就是问题 if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled 一切都完成了,Windows将选择下一个DataGridViewR
DataGridViews
开发一个程序。
在一个DatagridView
中有一个DataGridViewTextBoxColumn
,用户可以编辑该列。当用户输入完数字后,按键盘上的ENTER键。现在,DataGridView
执行所有的事件
,在所有事件之后,最后一件事就是问题
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
一切都完成了,Windows将选择下一个DataGridViewRow
,我无法阻止这一点
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
我试过了
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
几乎在我发现的每一件事上。遗憾的是,我只能在DataGridViewTextBoxColumn
未处于编辑模式时阻止ENTER键
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
这是我在编辑时找不到输入的方法
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
添加事件
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
private void dgr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress += new KeyPressEventHandler(dgr_KeyPress_NumericTester);
}
这是只接受数字输入的事件
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
private void dgr_KeyPress_NumericTester(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != 8) e.Handled = true;
}
详细说明:
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
当用户输入一个有一些依赖项的值时,我想给另一个控件焦点,这样他就可以纠正依赖项
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
我还尝试了DependingControl.Focus()
,但最后一个“enter”将是视图中的最后一个内容
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
有人知道如何防止这种情况吗?好吧,我设法找到了一种能满足你需求的方法(或者至少是做了最难的部分,我想你已经做了其他大部分工作),但解决方案让我毛骨悚然
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
最后,我在编辑单元格时“取消”enter键事件,以混合使用CellEndEdit
事件和SelectionChanged
事件
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
我引入了两个类级字段来存储一些状态,特别是在编辑单元格结束时我们所在的行,以及我们是否正在停止更改的选择
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
代码如下所示:
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
public partial class Form1 : Form
{
private int currentRow;
private bool resetRow = false;
public Form1()
{
InitializeComponent();
// deleted out all the binding code of the grid to focus on the interesting stuff
dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
// Use the DataBindingComplete event to attack the SelectionChanged,
// avoiding infinite loops and other nastiness.
dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
}
void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (resetRow)
{
resetRow = false;
dataGridView1.CurrentCell = dataGridView1.Rows[currentRow].Cells[0];
}
}
void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
resetRow = true;
currentRow = e.RowIndex;
}
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
dataGridView1.SelectionChanged += new EventHandler(dataGridView1_SelectionChanged);
}
}
您需要彻底测试它,以确保它完全符合您的需要。我只检查了在编辑控件外按enter键时是否停止行更改
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
正如我所说的——我对需要做这样的事情不太满意——它感觉非常脆弱,而且可能有奇怪的副作用。但是,如果您必须具有这种行为,并且测试得很好,我认为这是实现您想要的功能的唯一方法。我尝试通过从中继承customcolumn来更改网格的Enter行为
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
Textbox列并重写以下事件
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
return base.ProcessDialogKey(Keys.Tab);
else
return base.ProcessDialogKey(keyData);
}
因此,它不发送Enter键,而是模拟Tab的操作,该操作将移动到下一个单元格。希望这有帮助我知道这个问题很久以前就有人问过了,但我希望答案对那些将来搜索的人可能有用。最好的解决方案是使用自定义列,而对于textbox则很容易,因为我们将利用内置类
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
class Native
{
public const uint WM_KEYDOWN = 0x100;
[DllImport("user32.dll")]
public static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
}
//the column that will be added to dgv
public class CustomTextBoxColumn : DataGridViewColumn
{
public CustomTextBoxColumn() : base(new CustomTextCell()) { }
public override DataGridViewCell CellTemplate
{
get { return base.CellTemplate; }
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(CustomTextCell)))
{
throw new InvalidCastException("Must be a CustomTextCell");
}
base.CellTemplate = value;
}
}
}
//the cell used in the previous column
public class CustomTextCell : DataGridViewTextBoxCell
{
public override Type EditType
{
get { return typeof(CustomTextBoxEditingControl); }
}
}
//the edit control that will take data from user
public class CustomTextBoxEditingControl : DataGridViewTextBoxEditingControl
{
protected override void WndProc(ref Message m)
{
//we need to handle the keydown event
if (m.Msg == Native.WM_KEYDOWN)
{
if((ModifierKeys&Keys.Shift)==0)//make sure that user isn't entering new line in case of warping is set to true
{
Keys key=(Keys)m.WParam;
if (key == Keys.Enter)
{
if (this.EditingControlDataGridView != null)
{
if(this.EditingControlDataGridView.IsHandleCreated)
{
//sent message to parent dvg
Native.PostMessage(this.EditingControlDataGridView.Handle, (uint)m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32());
m.Result = IntPtr.Zero;
}
return;
}
}
}
}
base.WndProc(ref m);
}
}
然后我们谈到dgv本身,我使用了一个从DataGridView派生的新类,添加了我的列,并处理了wndproc中的enter键
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
void Initialize()
{
CustomTextBoxColumn colText = new CustomTextBoxColumn();
colText.DataPropertyName = colText.Name = columnTextName;
colText.HeaderText = columnTextAlias;
colText.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
this.Columns.Add(colText);
DataGridViewTextBoxColumn colText2 = new DataGridViewTextBoxColumn();
colText2.DataPropertyName = colText2.Name = columnText2Name;
colText2.HeaderText = columnText2Alias;
colText2.DefaultCellStyle.WrapMode = DataGridViewTriState.False;
this.Columns.Add(colText2);
}
protected override void WndProc(ref Message m)
{
//the enter key is sent by edit control
if (m.Msg == Native.WM_KEYDOWN)
{
if ((ModifierKeys & Keys.Shift) == 0)
{
Keys key = (Keys)m.WParam;
if (key == Keys.Enter)
{
MoveToNextCell();
m.Result = IntPtr.Zero;
return;
}
}
}
base.WndProc(ref m);
}
//move the focus to the next cell in same row or to the first cell in next row then begin editing
public void MoveToNextCell()
{
int CurrentColumn, CurrentRow;
CurrentColumn = this.CurrentCell.ColumnIndex;
CurrentRow = this.CurrentCell.RowIndex;
if (CurrentColumn == this.Columns.Count - 1 && CurrentRow != this.Rows.Count - 1)
{
this.CurrentCell = Rows[CurrentRow + 1].Cells[1];//0 index is for No and readonly
this.BeginEdit(false);
}
else if(CurrentRow != this.Rows.Count - 1)
{
base.ProcessDataGridViewKey(new KeyEventArgs(Keys.Tab));
this.BeginEdit(false);
}
}
如果需要在enter键上关闭表单,可以使用以下代码。我假设网格是只读的,您不需要查询按下enter键的情况
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
public class DataGridViewNoEnter : DataGridView
{
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
((Form)this.TopLevelControl).DialogResult = DialogResult.OK;
return false;
}
return base.ProcessDataGridViewKey(e);
}
}
你可以简单地完成它……
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
1…为该网格视图创建KeyDown事件。(转到gridview上的属性并双击KeyDown事件)
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
2…超过此代码-
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
if(e.KeyData == Keys.Enter)
{
e.Handled = true;
}
3…最后看起来是这样的
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
private void dgvSearchResults_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
e.Handled = true;
}
}
4.运行程序并查看
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyDown
If e.KeyData = Keys.Enter Then e.Handled = True
End Sub
这只是一个变通办法,不是真正的解决方案,但它是有效的。只要这样做,它就会正常工作
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
private void dataGridViewX1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
SendKeys.Send("{UP}");
SendKeys.Send("{Right}");
}
这个答案来得真晚
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
但我有完全相同的问题,不想缓存行等。
所以我搜索了一下,这是我对这个问题的解决方案。归功于
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
从DataGridView继承并添加以下代码(vb.net):
if (e.KeyData == Keys.Enter) e.SuppressKeyPress = true; // or e.Handled
这对我来说很好。当我试图离开一个DataGridViewCheckBoxCell
时,只有一个小错误,我不能设置resetRow,因为它会将我的焦点锁定在复选框中<代码>如果(dataGridView1.CurrentCell为DataGridViewCheckBoxCell)resetRow=false代码>我使用SelectedRow而不是更改CurrentCell属性,这在我的测试中不起作用。。。现在很好,谢谢你!也是一个很好的方式。也谢谢你!您只需覆盖ProcessCmdKey
,请参见[此处了解如何]()和[此处了解原因][2][2]: