IronPython DataGridView:通过一键获取值但不按 'Enter' 并移动到下一个单元格

IronPython DataGridView: Get Value from One Key Press But Without Pressing 'Enter' and Move to the Next Cell

这几天我一直在和困难作斗争。我已经阅读了 http://www.ironpython.info/ and book 'IronPython In Action' by Michael and Christian, and DataGridView class on https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview(v=vs.110).aspx,但我仍然缺乏一些知识和技能。 我的问题是如何从一次按键中获取值但不按 'Enter' 并移动到下一个单元格,这意味着当我在键盘上按一个数字但不按 'Enter' 时,该数字被传递到第一个单元格如 3,然后下一个单元格处于活动状态。序列是曲折的,如第 1 列 1 -> 行 1 列 2 -> ... -> 行 1 列 12 -> 行 2 列 12 -> 行 2 列 11。 我尝试了很多DataGridView的事件,例如'CellEnter'和'KeyPress',但都失败了。 如果你能给出一些关于它的提示,我将非常感激。 以下是我到目前为止的代码:

import clr

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

from System.Windows.Forms import Form
from System.Windows.Forms import DataGridView
from System.Windows.Forms import DataGridViewContentAlignment
from System.Windows.Forms import Application
from System.Windows.Forms import Control
from System.Windows.Forms import Clipboard
from System.Windows.Forms import DataFormats
from System.Windows.Forms import DataObject

from System.Drawing import Point
from System.Drawing import Size
from System.Drawing import Font
from System.Drawing import FontStyle
from System.Drawing import Color

from System import Text

from System.IO import MemoryStream

NUMROWS = 6
NUMCOLS = 12

data = [[-1 for x in range(NUMCOLS)] for x in range(NUMROWS)]


class DataGridForm(Form):
    def __init__(self, numcols, numrows):
        self.Text = 'DataGridView Cell Format Test'
        self.ClientSize = Size(98 * (numcols + 1), 25 * (numrows + 1))
        self.dgv = DataGridView()
        self.numcols = numcols
        self.numrows = numrows
        self.setupdatagridview()
        self.adddata()
        self.formatheaders()

    def setupdatagridview(self):
        self.dgv.Location = Point(0, 0)
        self.dgv.Size = Size(98 * (NUMCOLS + 1), 25 * (NUMROWS + 1))
        self.Controls.Add(self.dgv)
        # have to have columns defined before inserting rows
        self.dgv.ColumnCount = self.numcols
        # center all text in all data cells by default
        self.dgv.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
        #self.dgv.CellEnter += self.move
        #self.dgv.CellValueChanged +=self.move
        #self.dgv.Enter += self.move
        #self.dgv.CellStateChanged += self.move
        #self.dgv.ChangeUICues += self.move
        #self.dgv.EditingControlShowing += self.move
        #self.dgv.EditModeChanged += self.move
        #self.dgv.GotFocus += self.move
        #self.dgv.HandleCreated += self.move
        #self.dgv.KeyPress += self.move
        #self.dgv.KeyDown += self.move
        #self.dgv.KeyUp += self.move
        #self.dgv.MouseEnter += self.move
        #self.dgv.Move += self.move
        #self.dgv.TextChanged += self.move

        # add empty rows first
        for num in xrange(self.numrows):
            self.dgv.Rows.Add()
        # format empty cells
        self.dgv.AllowUserToAddRows = False
        self.dgv.AllowUserToDeleteRows = False
        self.dgv.ReadOnly = False
        self.dgv.ClearSelection()

    def formatheaders(self):
        for num in xrange(self.numcols):
            col = self.dgv.Columns[num]
            col.HeaderCell.Value = str(num + 1)
            # slightly left of center on headers
            col.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
            # sets font and font style
            col.HeaderCell.Style.Font = Font(Control.DefaultFont, FontStyle.Bold) 
            col.HeaderCell.Style.ForeColor = Color.MidnightBlue
        # put numbers on rows
        for num in xrange(self.numrows):
            row = self.dgv.Rows[num]
            # get sequential numeric label on side of row
            row.HeaderCell.Value = str(num + 1)
            # sets font and font style
            row.HeaderCell.Style.Font = Font(Control.DefaultFont, FontStyle.Bold)
            row.HeaderCell.Style.ForeColor = Color.Blue
        self.dgv.TopLeftHeaderCell.Value = 'Score'
        self.dgv.TopLeftHeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
        self.dgv.TopLeftHeaderCell.Style.Font = Font(Control.DefaultFont, FontStyle.Bold)
        self.dgv.TopLeftHeaderCell.Style.ForeColor = Color.Blue
        self.dgv.RowHeadersWidth = 60

    def adddata(self):
        for num in xrange(self.numrows):
            row = self.dgv.Rows[num]
            dat = (datax for datax in data[num]) 
            for cell in row.Cells:
                cell.Value = dat.next()
    """            
    def move(self, sender, event):
        print 'move'
    """
dataGridForm = DataGridForm(NUMCOLS, NUMROWS)
Application.Run(dataGridForm)

我发现 EditingControlShowing 可以引发事件,self.dgv.CurrentCell = self.dgv.Rows[currentRow].Cells[currentCol + 1] 可以移动单元格。但是,我无法获取输入的数字,table 是 none。我这部分的代码如下。

def move(self, sender, event):       
    currentCol = self.dgv.CurrentCellAddress.X
    currentRow = self.dgv.CurrentCellAddress.Y

    """        
    print self.IsInputChar('a')
    if self.IsInputChar('a'):
        self.dgv.CurrentCell.Value = 8
    else:
        self.dgv.CurrentCell.Value = 10
    """

    if currentRow % 2 == 0 and currentCol != NUMCOLS - 1:
        self.dgv.CurrentCell = self.dgv.Rows[currentRow].Cells[currentCol + 1]
    elif currentRow % 2 == 0 and currentCol == NUMCOLS - 1:
        self.dgv.CurrentCell = self.dgv.Rows[currentRow + 1].Cells[currentCol]
    elif currentRow % 2 != 0 and currentCol != 0:
        self.dgv.CurrentCell = self.dgv.Rows[currentRow].Cells[currentCol - 1]
    elif currentRow % 2 != 0 and currentRow != NUMROWS - 1 and currentCol == 0:
        self.dgv.CurrentCell = self.dgv.Rows[currentRow + 1].Cells[currentCol]
    else:
        None

我找到了一个方法:首先通过"self.dgv.EditingControlShowing += self.keyPress"触发EditingControlShowing事件;然后通过调用 KeyPress def keyPress(自我,发件人,事件): event.Control.KeyPress += self.move 现在我可以通过 "self.dgv.CurrentCell.Value = event.KeyChar" 获得价值。 然而,单元格值和移动并不总是正确的,这需要解决。

我终于自己搞定了。使用 KeyPress 事件并设置 ReadOnly 属性 true.