【问题标题】:vb.net DataGridView prevent user clicking on columnvb.net DataGridView 防止用户点击列
【发布时间】:2020-07-17 09:42:15
【问题描述】:

我有一个 DataGridView (DGV),我从 SQLite DB 手动添加项目
我的选择模式设置是 CellSelect 和 FullRowSelect 可能已经尝试过其他的

错误和问题因用户单击 DGV 的位置而异
现在的代码只有在选择标题 PID 下的空列时才会发生错误
And when the Column Header PID is selected See Posted Image
我已将错误作为 cmets 包含在代码中

我想解决的问题之一是禁用所有列上的所有排序
添加到 DGV 的数据是一个主键,它是一个整数 PID
还有一些文本是 NVARCHAR(2048) 这个文本来自 RichTextBox

要解决的两个最大问题是防止错误,是的,这些是问题

    Private Sub PopulateDGV()
    For Each header As DataGridViewHeaderCell In dgvOne.Rows
        'header.SortMode = DataGridViewColumnHeaderCell.NotSortable
    Next
    'The code Above NOT Working

    'ERRORS
    'System.InvalidOperationException 'Column's SortMode cannot be set to Automatic
    'While the DataGridView control's SelectionMode is set to ColumnHeaderSelect.'
    'Your app has entered a break state, but there is no code to show because all 
    'threads were executing external code (typically system Or framework code).

    'dgvOne = DataGridViewColumnSortMode.NotSortable
    Dim str2 As String
    Dim s1 As Integer
    Dim dbName As String = "Word.db"
    Dim conn As New SQLiteConnection("Data Source =" & dbName & ";Version=3;")
    Dim valuesList As ArrayList = New ArrayList()

    'Read from the database
    Dim cmd As SQLiteCommand = New SQLiteCommand("Select * FROM ParentTable", conn)
    conn.Open()
    Dim rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader

    'Set Design of the DataGridView
    dgvOne.DefaultCellStyle.Font = New Font("Tahoma", 10)

    dgvOne.ColumnCount = 2
    dgvOne.Columns(0).Width = 60
    dgvOne.Columns(1).Width = 420
    'Set Col Header Size Mode = Enabled
    'Set Col Header Default Cell Styles DO in Properties
    dgvOne.ColumnHeadersHeight = 34

    'DGV Header Names
    dgvOne.Columns(0).Name = "PID"
    dgvOne.Columns(1).Name = "Entry Data"

    'Read from DB Table add to DGV row
    While rdr.Read()
        valuesList.Add(rdr(1)).ToString()
        lbOne.Items.Add(rdr(1)).ToString()
        s1 = rdr(0).ToString
        str2 = rdr(1)
        dgvOne.Rows.Add(s1, str2)
    End While

    'Add Blank rows to DGV
    For iA = 1 To 4
        dgvOne.Rows.Add(" ")
    Next

    rdr.Close()
    conn.Close()

End Sub

Private Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick

    If (e.RowIndex = -1) Then
        MessageBox.Show("No Clicking Here")
        Return
    End If

    If dgvOne.CurrentCell.Value Is Nothing Then
        tbMessage.Text = "NO Data Here"
        Return
    ElseIf e.RowIndex >= 0 Then

        tbMessage.Text = e.RowIndex
        Dim str2 As String
        Dim s2 As String
        Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
        s2 = row.Cells(0).Value.ToString
        str2 = row.Cells(1).Value.ToString
        strB = str2
        rtbEnter.Text = strB
        'ERRORS
        'System.NullReferenceException
        'HResult = 0x80004003
        'Message = Object reference Not Set To an instance Of an Object.
        'Source = TestSQL
        'StackTrace:
        'at TestSQL.frmThree.dgvTwo_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e) in C:\Users\Dwight\source\repos\TestSQL\TestSQL\frmThree.vb:line 117

    End If
End Sub

【问题讨论】:

  • 首先,我建议您了解列和单元格之间的区别,然后编辑您的问题以引用正确的问题。您正在使用“列”清除应该使用“单元格”的地方,这会混淆整个事情。
  • “要解决的两个最大问题”。 SO 问题需要解决一个特定问题,因此根据定义,您的问题是不可接受的。

标签: vb.net datagridview


【解决方案1】:

要防止对列进行排序(这似乎是您的主要问题),请执行以下操作:

dgvOne.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
dgvOne.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable

您还需要注意单元格中的空值。所以在“CellMouseClick”事件中,添加如下内容:

If row.Cells(1).Value IsNot Nothing Then
   str2 = row.Cells(1).Value.ToString
End If

【讨论】:

  • 为了让代码更简洁一点是值得的
【解决方案2】:

@Brian M 斯塔福德 感谢您让我们朝着正确的方向前进 矢量这很容易弄清楚是否有人会分享一些信息 好问题的猜测是您正在节省字节 因为这里只有三 (3) 列是他们在 DGV 中的名称和位置
Col -1 Col 0 Col 1 和 YES 他们从左到右
就这样没有人感到困惑 行从上到下
第 0 行
第 1 行
因此,您真正需要的只是一项与 ColumnIndex 相辅相成的测试
此代码仅允许单击第 1 列,前提是该 CELL
中有文本 只需操作测试,您就可以为用户提供额外的选择

    Public Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick

    If e.RowIndex = -1 Or e.ColumnIndex = -1 Then
        'tbMessage.Text = "Col " & e.ColumnIndex & " ROW " & e.RowIndex
        tbMessage.Text = "No Clicking Here"
        Return
    End If

    If dgvOne.CurrentCell.Value Is Nothing Then
        tbMessage.Text = "NO Data Here"
        Return
    End If
    Dim s3 As Integer
    s3 = e.ColumnIndex
    If s3 = 0 Then
        'tbMessage.Text = "S3 " & e.ColumnIndex
        tbMessage.Text = "No Clicking Here"
        Return
    End If

    Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
    Dim col As DataGridViewColumn = dgvOne.Columns(e.ColumnIndex)
    If e.RowIndex >= 0 And e.ColumnIndex <> -1 Then

        tbMessage.Text = "Data Sent to RTB"
        Dim str2 As String
        str2 = row.Cells(1).Value.ToString
        rtbEnter.Text = str2
    End If

End Sub

【讨论】:

    【解决方案3】:

    在阅读了所有不错的答案并寻找一种方法来解决我的众多问题和大量试验和错误之后,这是一种防止用户点击 DataGridView 上的各个位置的方法

        Public Sub dgvTwo_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvOne.CellMouseClick
    
        If e.RowIndex = -1 Or e.ColumnIndex = -1 Then
            'tbMessage.Text = "Col " & e.ColumnIndex & " ROW " & e.RowIndex
            tbMessage.Text = "No Clicking Here"
            rtbEnter.Clear()
            Return
        End If
    
        Dim str1 As String
        Dim str2 As String
        Dim s1 As Integer
        Dim row As DataGridViewRow = dgvOne.Rows(e.RowIndex)
        str1 = dgvOne.CurrentRow.Cells(0).Value.ToString
        If str1 IsNot " " Then
            If str1 Is " " Then
                Return
            End If
            tbMessage.Text = "Text Sent to RTB"
            s1 = row.Cells(0).Value
            'Dim strInt As String
            gv_passInt = s1.ToString
            str2 = row.Cells(1).Value.ToString
            rtbEnter.Text = str2
            gv_passStr = str2
            Return
        End If
        rtbEnter.Clear()
        tbMessage.Text = "No Data Here"
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多