且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Datagridview编辑问题

更新时间:2023-02-19 20:04:32

嗨Denham,


对于迟到的回复感到抱歉。


>>但是:如果用户点击一个空单元格,例如假设单元格0到30已填满且用户单击单元格80,他可以直接在那里输入一个值,这会扰乱整个苹果车。


似乎我无法重现这个问题,我测试了你的代码,如果我点击单元格80,焦点将返回第一个单元格,所以我可以没有为单元格80输入值,m aybe我恢复问题的过程
是错误的,请您提供更多详细信息吗?


如果你能提供一个gif来重现你的步骤,我们将不胜感激。


问候,


Frankie


Hi,

I am using VS community 2015 for VB 2015.

I have a datagridview which has 10 columns each of 24 rows as a CRC calculator on a windows form. There are also 2 textboxes, tbxCRC & tbxIn, 2 buttons, btnExit & btnClear.

In the datagridview, even columns are just indices 0 to 124, odd columns are values. Initially all of the odd column rows are pre-loaded with the null string "".  The values are passed from a textbox which has focus that the user enters hex data into, and that is fine. When the string length in the box is 2, it is passed to the datagridview from c1, r 0, the row / column is incremented as required, and the new CRC value is calculated and displayed in tbxCRC on every entry.

If there is an entry error, the user clicks in the datagridview cell that has the error, the value is deleted and replaced by a null value string and the CRC is re-calculated to the empty cell, and if a new value is entered via the textbox, and this is not at the end of the list, the CRC is re-calculated for the complete list, and again that all works.

However: If the user clicks in an empty cell, for example suppose that cells 0 to 30 are filled and the user clicks in cell 80, he can enter a value in there directly and that upsets the whole apple cart.

The datagridview is set to read only, but still cells can be accessed and written to. Is there any clever way to stop this but still allow the CellMouseClick, (or other mouse action) event to delete the cell contents?

With care it works and does the CRC-8 as I want, but there are so many possible ways to create an error that it would be impossible to issue as a useful program.

Any help would be appreciated.

My code is here:

Public Class Form1

    Dim i, j, ei, cl, rw As Byte
    Dim rta As Byte = 25  'rows to add
    Dim crc As Integer
    Dim posc As Integer
    Dim posr As Integer
    Dim oldcrc, Newcrc As Integer
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SetupDGVI()
        tbxIn.Focus()

    End Sub

    Private Sub SetupDGVI()
        DGVI.EditMode = DataGridViewEditMode.EditProgrammatically
        DGVI.ColumnCount = 10
        With DGVI
            For j = 0 To 9   'ZERO INDEXED YOU MUPPET
                .Columns(j).Width = 60
            Next
            .Columns(0).Name = "Addr"
            .Columns(1).Name = "Hex"
            .Columns(2).Name = "Addr"
            .Columns(3).Name = "Hex"
            .Columns(4).Name = "Addr"
            .Columns(5).Name = "Hex"
            .Columns(6).Name = "Addr"
            .Columns(7).Name = "Hex"
            .Columns(8).Name = "Addr"
            .Columns(9).Name = "Hex"
            For j = 0 To rta - 1
                .Rows.Add(j, "", j + 25, "", j + 50, "", j + 75, "", j + 100, " ")
            Next
            For j = 0 To 9
                .Columns(j).ReadOnly = True
            Next j
            '.CurrentCell = DGVI(1, 0)
            'ei = 0
            '.BeginEdit(1)
            posc = 1
            posr = 0
        End With


    End Sub

    Private Function Get_CRC(ByVal vtg As String, crc As Byte) As String
        Try
            Dim fb As Byte
            Dim vtc As Byte
            vtc = Convert.ToByte(vtg, 16)                            'Base 16 (Hex)
            i = 8
            Do
                fb = (crc Xor vtc) And 1
                vtc = vtc >> 1
                crc = crc >> 1
                If fb Then
                    crc = crc Xor 140      '0x8C
                End If

                i -= 1
            Loop Until i = 0

        Catch ex As Exception
            crc = 255
        End Try
        Return crc
    End Function

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles BtnClr.Click
        For i = 1 To 9 Step 2
            For j = 0 To rta - 1
                DGVI(i, j).Value = ""
            Next j
        Next i
        posc = 1
        posr = 0
        oldcrc = 0
        tbxIn.Text = Nothing
        tbxIn.Focus()
        tbxCRC.Text = Nothing
    End Sub

    Public Function IsHex(ByVal str As String) As Boolean
        Try
            Dim num As Long = CLng("&H" & str)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
        Me.Close()
    End Sub


    Private Sub tbxIn_KeyUp(sender As Object, e As KeyEventArgs) Handles tbxIn.KeyUp
        Dim inval As String
        inval = tbxIn.Text.ToUpper
        If inval.Length = 2 Then
            If IsHex(inval) Then
                DGVI.CurrentCell = DGVI(posc, posr)
                DGVI.CurrentCell.Value = inval
                doCRC(inval, oldcrc)
                posr += 1
                If posr >= rta Then
                    posc = posc + 2
                    If posc = 11 Then
                        MsgBox("Dataset is full. Please clear table", vbOK)
                    End If
                    posr = 0
                End If
                DGVI.CurrentCell = DGVI(posc, posr)
                DGVI.CurrentCell.Value = DGVI.CurrentCell
                If DGVI.CurrentCell.Value <> "" Then  'If next box is not empty, redo whole crc to empty string 
                    redocrc()
                End If
            Else MsgBox("Hex Values only", vbOK)
            End If
            tbxIn.Text = Nothing
        End If

    End Sub
    Private Sub doCRC(ins As String, oldv As Byte)
        Newcrc = Get_CRC(ins, oldv)
        oldcrc = Newcrc              'updates saved value
        tbxCRC.Text = Newcrc.ToString("X2")


    End Sub

    Private Sub DGVI_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DGVI.CellMouseClick

        posc = DGVI.CurrentCellAddress.X 'Column  
        posr = DGVI.CurrentCellAddress.Y 'row
        clearcell()
        ' If posr > 0 Then
        ' posr -= 1
        ' Else posr = 24
        'If posc > 1 Then
        'posc -= 1
        'posc -= 1
        '    Else posc = 1
        'End If

        'End If
        ' DGVI.CurrentCell = DGVI(posc, posr)  'activates previous cell

    End Sub
    Private Sub redocrc()
        Dim cellval As String
        Dim il, jl As Byte
        oldcrc = 0
        For jl = 1 To 9 Step 2  'get all cell values and recalculate crc
            For il = 0 To rta - 1
                DGVI.CurrentCell = DGVI(jl, il)
                cellval = DGVI.CurrentCell.Value
                If cellval = "" Then
                    'clearcell()
                    Exit Sub
                Else
                    doCRC(cellval, oldcrc)
                End If
            Next il
        Next jl

    End Sub
    Public Sub clearcell()
        DGVI.CurrentCell.Value = ""

        tbxIn.Text = ""
        tbxIn.Focus()
        redocrc()

    End Sub
End Class

Hi Denham,

Sorry for the late reply.

>>However: If the user clicks in an empty cell, for example suppose that cells 0 to 30 are filled and the user clicks in cell 80, he can enter a value in there directly and that upsets the whole apple cart.

It seems I can not reproduce this issue, I tested your code and if I click the cell 80, the focus will return the first cell, so I can not input a value for the cell 80, maybe the process of my restoring the problem is wrong, could your please provide more details about it?

It will be more appreciate if you can provide a gif to reproduce your steps.

Regards,

Frankie