0
votes

I've been struggling with the difficulty for a few days. I've read on 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, but I'm still lack of some knowledge and skills. My question is how to get value from one key press but without pressing 'Enter' and Move to the next cell, which means when I press one number on keyboard but without pressing 'Enter', the number is passed into the first cell such as 3, and then the next cell is active. The sequence is meander, like row 1 col 1 -> row 1 col 2 -> ... -> row 1 col 12 -> row 2 col 12 -> row 2 col 11. I tried many events of DataGridView such as 'CellEnter' and 'KeyPress', but failed. If you could give some hints about it, I'll appreciate it very much. The following is my code up to now:

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)
3

3 Answers

1
votes

I finally work it out by myself. Use KeyPress event and set ReadOnly property true.

0
votes

I've found EditingControlShowing to evoke an event, and self.dgv.CurrentCell = self.dgv.Rows[currentRow].Cells[currentCol + 1] to move cell. However, I cannot get the input number and the table is none. My code of this part is as below.

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
0
votes

I found a way: firstly evoke EditingControlShowing event by "self.dgv.EditingControlShowing += self.keyPress"; and then evoke KeyPress by def keyPress(self, sender, event): event.Control.KeyPress += self.move And now I can get value by "self.dgv.CurrentCell.Value = event.KeyChar". However, cell value and movement is not always correct, which needs to be resolved.