键入时datagridview更新

时间:2014-07-04 16:03:07

标签: c# vb.net events datagridview cell

我正在制作会计应用程序,我遇到了一个小问题。我需要我的datagridview进行必要的单元格计算,而不是在我按下一个键或进行任何其他类型的验证之后我在单元格中写入...因为用户可能忘记这样做。

所以我有这个,我的问题是我应该在输入时使用什么事件来验证dgw单元格?还是有另一种方法可以做到这一点?

Private Sub NRCD_produseDataGridView_CellValueChanged(ByVal sender As Object, ByVal e 
   As System.Windows.Forms.Da-taGridViewCellEventArgs) 
   Handles NRCD_produseDataGridView.???????

   // doesn't matter what is here 

End Sub

感谢名单

2 个答案:

答案 0 :(得分:0)

正如您所观察到的,CellValueChanged事件对于这种情况并不合适。为什么?因为编辑控件的值尚未推回DataGridView。您正在寻找的事件是EditingControlShowing。这样,您就可以在编辑时向TextBox中显示的实际编辑控件(ComboBoxDataGridViewCell等)添加句柄。请注意,当单元格不处于编辑模式时,单元格只是一个"图像"由网格绘制的编辑控件,它不是一个实际的控件。

在询问与DataGridView相关的问题时,分享以下内容非常重要:

  • 网格是否绑定到数据源?
  • 如果是,底层数据源的类型是什么?
  • 您是否在VirtualMode
  • 中运行了网格

现在,由于您还没有共享任何此类内容,因此以下示例表单假设网格为:

  • 绑定到DataTable
  • 以正常模式运行。

enter image description here

Public Class Form1

    Public Sub New()
        Me.InitializeComponent()
        Me.ClientSize = New Size(500, 300)
        Me.table = New DataTable()
        Me.table.Columns.Add("Text", GetType(String))
        Me.table.Columns.Add("Length", GetType(Integer))
        Me.table.Rows.Add("apple", 5)
        Me.table.Rows.Add("banana", 6)
        Me.table.Rows.Add("orange", 6)
        Me.textColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Text", .HeaderText = "Text", .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill}
        Me.lengthColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Length", .ReadOnly = True, .HeaderText = "Length (Computed)", .Width = 200, .MinimumWidth = 200}
        Me.grid = New DataGridView() With {.Dock = DockStyle.Fill, .AutoGenerateColumns = False, .DataSource = Me.table}
        Me.grid.Columns.AddRange({Me.textColumn, Me.lengthColumn})
        Me.Controls.Add(Me.grid)
    End Sub

    Private Sub HandleEcShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles grid.EditingControlShowing
        If (Me.grid.CurrentCell.ColumnIndex = Me.textColumn.Index) Then
            Dim ec As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
            Me.UnhookEc(ec) 'Important: Remove handles to avoid recursion.
            Me.HookEc(ec)
        End If
    End Sub

    Private Sub HandleEcTextChanged(sender As Object, e As EventArgs)
        Dim ec As DataGridViewTextBoxEditingControl = DirectCast(sender, DataGridViewTextBoxEditingControl)
        Dim cell As DataGridViewTextBoxCell = DirectCast(Me.grid.CurrentCell, DataGridViewTextBoxCell)
        Me.grid.Rows(cell.RowIndex).Cells(Me.lengthColumn.Index).Value = ec.Text.Length
    End Sub

    Private Sub HandleEcDisposed(sender As Object, e As EventArgs)
        Me.UnhookEc(TryCast(sender, DataGridViewTextBoxEditingControl)) 'Important: This will ensure removal of the hooked handles.
    End Sub

    Private Sub HookEc(ec As DataGridViewTextBoxEditingControl)
        If (Not ec Is Nothing) Then
            AddHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
            AddHandler ec.Disposed, AddressOf Me.HandleEcDisposed
        End If
    End Sub

    Private Sub UnhookEc(ec As DataGridViewTextBoxEditingControl)
        If (Not ec Is Nothing) Then
            RemoveHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
            RemoveHandler ec.Disposed, AddressOf Me.HandleEcDisposed
        End If
    End Sub

    Private WithEvents table As DataTable
    Private WithEvents grid As DataGridView
    Private WithEvents textColumn As DataGridViewTextBoxColumn
    Private WithEvents lengthColumn As DataGridViewTextBoxColumn

End Class

答案 1 :(得分:0)

我修改了代码并添加了一个TextBox。

如果修改了,例如第一个单元格,那么我单击TextBox并再次单击修改后的单元格,尝试再次在同一单元格中写入,这是一种罕见的效果,并且未在同一单元格中正确写入。 您需要更改行并返回上一个单元格以在该单元格中回写。

我对这种代码工作感兴趣,但这并没有产生这种奇怪的效果。

如果我在事件HandleEcTextChanged(...)中删除以下代码行

Me.grid.Rows(cell.RowIndex).Cells(Me.lengthColumn.Index).Value = ec.Text.Length

问题不会发生,但我需要以编程方式更新“长度”列。

此外,如果datagridview连接到数据库,则会出现错误"数据表的索引已损坏。"

重现问题的步骤:

  1. 修改datagridview的第一个单元格" apple"。
  2. 点击TexBox" 0000000"。
  3. 点击上面修改过的单元格。
  4. 在当前单元格中输入任意值。
  5. 在上一点出现问题。不要在单元格中正确写入。
  6. 请帮助。

    坦克。

    Public Class TextBoxDirectCast
    
        Private WithEvents table As DataTable
        Private WithEvents grid As DataGridView
        Private WithEvents textColumn As DataGridViewTextBoxColumn
        Private WithEvents lengthColumn As DataGridViewTextBoxColumn
        Private WithEvents texboxtext As TextBox
    
        Public Sub New()
            Me.InitializeComponent()
            Me.ClientSize = New Size(400, 300)
            Me.table = New DataTable()
            Me.table.Columns.Add("Text", GetType(String))
            Me.table.Columns.Add("Length", GetType(Integer))
            Me.table.Rows.Add("apple", 5)
            Me.table.Rows.Add("banana", 6)
            Me.table.Rows.Add("orange", 6)
            Me.textColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Text", .HeaderText = "Text", .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill}
            Me.lengthColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Length", .ReadOnly = True, .HeaderText = "Length (Computed)", .Width = 200, .MinimumWidth = 200}
            Me.grid = New DataGridView() With {.Dock = DockStyle.Top, .AutoGenerateColumns = False, .DataSource = Me.table, .TabIndex = 0}
            Me.grid.Columns.AddRange({Me.textColumn, Me.lengthColumn})
            Me.Controls.Add(Me.grid)
            Me.texboxtext = New TextBox With {.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left, .Text = "0000000", .Location = New Point(10, Me.ClientSize.Height - 30), .TabIndex = 1}
            Me.Controls.Add(Me.texboxtext)
            Me.texboxtext.BringToFront()
        End Sub
    
        Private Sub HandleEcShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles grid.EditingControlShowing
            If (Me.grid.CurrentCell.ColumnIndex = Me.textColumn.Index) Then
                Dim ec As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
                Me.UnhookEc(ec) 'Important: Remove handles to avoid recursion.
                Me.HookEc(ec)
            End If
        End Sub
    
        Private Sub HandleEcTextChanged(sender As Object, e As EventArgs)
            Dim ec As DataGridViewTextBoxEditingControl = DirectCast(sender, DataGridViewTextBoxEditingControl)
            Dim cell As DataGridViewTextBoxCell = DirectCast(Me.grid.CurrentCell, DataGridViewTextBoxCell)
            Me.grid.Rows(cell.RowIndex).Cells(Me.lengthColumn.Index).Value = ec.Text.Length
        End Sub
    
        Private Sub HandleEcDisposed(sender As Object, e As EventArgs)
            Me.UnhookEc(TryCast(sender, DataGridViewTextBoxEditingControl)) 'Important: This will ensure removal of the hooked handles.
        End Sub
    
        Private Sub HookEc(ec As DataGridViewTextBoxEditingControl)
            If (Not ec Is Nothing) Then
                AddHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
                AddHandler ec.Disposed, AddressOf Me.HandleEcDisposed
            End If
        End Sub
    
        Private Sub UnhookEc(ec As DataGridViewTextBoxEditingControl)
            If (Not ec Is Nothing) Then
                RemoveHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
                RemoveHandler ec.Disposed, AddressOf Me.HandleEcDisposed
            End If
        End Sub
    
    End Class