简体   繁体   中英

Vb.Net 2013 Datagridview issue on DirectCast TextBox

I have this code, if modified, for example the first cell, then I click on the TextBox and click again on the modified cell, to try writing again in the same cell, a rare effect and does not properly written in the same cell. You need to change row and return to the previous cell to write back in that cell.

I am interested in the code work this way, but that does not make this weird effect.

If I remove the following line of code in the event HandleEcTextChanged (...)

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

the problem does not happen, but I need to update the Length column programmatically.

In addition, if the datagridview is connected to a database, you get an error "The index of the datatable it is damaged."

Steps to reproduce the problem:

  1. Modify the first cell of datagridview "apple".
  2. Click the TexBox "0000000".
  3. Click on the cell modified above.
  4. Enter any value in the current cell.
  5. In the previous point the problem occurs. Do not write properly in the cell.

Help please.

Tanks.

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

Use directcast to access your cells. Here's an example code I wrote to access a dynamically generated textbox.

    Dim txt = New TextBox()
    txt.Name = "name1"
    txt.Size = New Size(200, 70)
    txt.Location = New Point(40, 40)
    txt.Text = "I am a new textbox"
    Me.Controls.Add(txt)
    DirectCast(Me.Controls("name1"), TextBox).Text = "Some stuff here" 'The magic happens here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM