我只需要允许进入可编辑的datagridview细胞一个字符(每隔一列的奇数号的,是可编辑的); 如果用户增加了第二个字符,而在这些细胞中的一个,光标应该移动到下一个单元格下来,把那第二个值有(再次下调该键移动再次按下,等等)。 如果在电网(第12行)的底部,就应该移动到0行也移动两列到右边。
我试着这样做:
private void dataGridViewPlatypus_KeyDown(object sender, KeyEventArgs e) {
var currentCell = dataGridViewPlatypus.CurrentCell;
int currentCol = currentCell.ColumnIndex;
int currentRow = currentCell.RowIndex;
if (currentCell.Value.ToString().Length > 0) {
if (currentRow < 11) {
dataGridViewPlatypus.CurrentCell.RowIndex = currentRow+1;
} else if (currentRow == 11) {
currentCell.RowIndex = 0;
currentCell.ColumnIndex = currentCell.ColumnIndex + 2;
dataGridViewPlatypus.CurrentCell = currentCell;
}
}
}
......但我得到迷途的rowIndex和ColumnIndex无法被分配到短信息,因为它们是只读的。
那么,如何才能做到这一点?
警告:我知道,我还必须添加逻辑移动到第1列,如果目前在最后编辑栏的底部。
UPDATE
从tergiver的答案,这是我这么远,但我不知道如何前进到下一个单元格。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (this.ActiveControl == dataGridViewPlatypus)
{
var currentCell = dataGridViewPlatypus.CurrentCell;
if (currentCell.Value.ToString().Length == 1)
{
;//Now what?
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
更新2
感谢所有; 这是我用得到它几乎什么工作(我仍然希望能够允许用户只需按住按键,并在随后的细胞不断输入的值):
private void dataGridViewPlatypus_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
int columnIndex = (((DataGridView)(sender)).CurrentCell.ColumnIndex);
if (columnIndex % 2 == 1) {
e.Control.KeyDown -= TextboxNumeric_KeyDown;
e.Control.KeyDown += TextboxNumeric_KeyDown;
e.Control.KeyUp -= TextboxNumeric_KeyUp;
e.Control.KeyUp += TextboxNumeric_KeyUp;
}
}
private void TextboxNumeric_KeyDown(object sender, KeyEventArgs e) {
var tb = sender as TextBox;
if (tb != null) {
tb.MaxLength = 1;
}
}
// TODO: Now need to find a way to be able to just press down once
private void TextboxNumeric_KeyUp(object sender, KeyEventArgs e) {
var tb = sender as TextBox;
if (tb != null && tb.TextLength >= 1) {
if (dataGridViewPlatypus.CurrentCell.RowIndex != dataGridViewPlatypus.Rows.Count - 1) {
dataGridViewPlatypus.CurrentCell = dataGridViewPlatypus[
dataGridViewPlatypus.CurrentCell.ColumnIndex,
dataGridViewPlatypus.CurrentCell.RowIndex + 1];
} else { // on last row
this.dataGridViewPlatypus.CurrentCell = this.dataGridViewPlatypus.CurrentCell.ColumnIndex != dataGridViewPlatypus.Columns.Count - 1 ? this.dataGridViewPlatypus[this.dataGridViewPlatypus.CurrentCell.ColumnIndex + 2, 0] : this.dataGridViewPlatypus[1, 0];
}
}
}
该CurrentCell
的财产DataGridView
有一个二传手,让您在新的细胞通过。
一种方法解决这个问题是处理EditingControlShowing
网格的事件并附加KeyPress
处理程序,像这样的编辑控制:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if ((int)(((System.Windows.Forms.DataGridView)(sender)).CurrentCell.ColumnIndex) == 1)
{
e.Control.KeyPress += TextboxNumeric_KeyPress;
}
}
然后在按键处理您有:
private void TextboxNumeric_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
if (tb.TextLength >= 5)
{
dataGridView1.CurrentCell = dataGridView1[dataGridView1.CurrentCell.ColumnIndex + 1, dataGridView1.CurrentCell.RowIndex];
}
}
上面的逻辑当然是不正确的你的情况,但在新CurrentCell传递站(从电网获取所需的细胞后)的原则。
细胞有Selected
属性可以设置。 仅仅通过行和列的索引访问的单元格。
我相信你可以做
dgView.rows[0].cells[0].selected = true
,
这将使你在(0,0)的单元格或第一行,第一列相交。 或者,你可以抓住这样的行:
我想这就是类- > DataGridViewRow row = dgView.rows[0]
然后
row[0].cells[0].Selected = true
。
Column 1 Column 2
Row 1 [this guy][ ]
Row 2 [ ][ ]
编辑:
要通过获得下一个单元格,只是做:
sameRow.cells[currentCell.ColumnIndex+1].Selected = true;
我可能已经错过了在那里的一些市值,但你明白了吧。
的KeyDown在DGV不会起作用,因为一个DataGridViewTextBoxColumn使用就地TextBox控件,这是它对可见光和移动到位,及时为编辑。
由于只有一个就地文本框中的所有文本列,您可以订阅其KeyDown事件,但有可能是鸡和蛋的问题与获得该控件的引用。
更好的办法是使用窗体的ProcessCmdKey重写并且有执行这个逻辑。 当按下按键时,检查DGV是ACTIVECONTROL,检查当前单元格是文本单元,检查单元格已经包含一个字符,然后允许处理的关键前更改当前单元格。
更新-乘坐2
using System;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class Item
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
}
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
DataGridView dataGridViewPlatypus;
public Form1()
{
ClientSize = new Size(480, 260);
Controls.Add(dataGridViewPlatypus = new DataGridView
{
Dock = DockStyle.Fill,
DataSource = Enumerable.Range(1, 10).Select(i => new Item { A = "", B = "", C = "", D = "" }).ToList(),
});
}
[DllImport("User32.dll")]
extern static int PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.Msg == 256) // WM_KEYDOWN
{
if (this.ActiveControl == dataGridViewPlatypus.EditingControl)
{
var currentCell = dataGridViewPlatypus.CurrentCell;
if (currentCell.OwningColumn is DataGridViewTextBoxColumn && dataGridViewPlatypus.EditingControl.Text.Length > 0)
{
int rowIndex = currentCell.RowIndex;
int columnIndex = currentCell.ColumnIndex;
if (++columnIndex >= dataGridViewPlatypus.Columns.Count)
{
columnIndex = 0;
if (++rowIndex >= dataGridViewPlatypus.Rows.Count)
rowIndex = 0;
}
dataGridViewPlatypus.CurrentCell = dataGridViewPlatypus[columnIndex, rowIndex];
PostMessage(dataGridViewPlatypus.Handle, msg.Msg, msg.WParam, msg.LParam);
return true; // Don't process this message, we re-sent it to the DGV
}
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
我有一个过程,就是炸弹,如果所选择的小区是一列。 因此,在该进程的按钮的代码,这是它的第一个代码:(顺便说一句,我使用的小区选择在网格)
if (dgvGrid.CurrentCell.ColumnIndex == 0) // first column
dgvGrid.Rows[dgvGrid.CurrentCell.RowIndex].Cells[1].Selected = true;
这有效地“标签”到下一列,然后我的过程的其余部分工作。
文章来源: How can I programmatically move from one cell in a datagridview to another?