Link to home
Start Free TrialLog in
Avatar of koossa
koossa

asked on

DirectCast DataGridViewTextBoxCell to TextBox

The following code is working
  Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    Dim MyTextBox As TextBox
    If TypeOf e.Control Is TextBox Then
      MyTextBox = DirectCast(e.Control, TextBox)
    End If
  End Sub

Open in new window


But I want to cast the e.control to my own class that Inherits TextBox, is that possible?
ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of koossa
koossa

ASKER

Try to make an easy autocomplete on all the textbox cells.
Just save a query for each column and then when the user type something in the grid, run a "Where" on the query and just update the AutoCompleteStringCollection with the items returned on the inhereted textbox class.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of koossa

ASKER

Is there any way that I can get the character / text entered in the cell, on the EditingControlShowing event?
Why don't you use the keydown/keypress event?
Avatar of koossa

ASKER

As far as I can see neither of them get triggered.
You'll have to manually attach the handlers. Extending jpaulino's example:

Public Class Form1

    Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
        Dim txt As DataGridViewTextBoxEditingControl
        txt = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

        Dim MySource As New AutoCompleteStringCollection()
        MySource.AddRange(New String() _
                            { _
                                "January", _
                                "February", _
                                "March", _
                                "April", _
                                "May", _
                                "June", _
                                "July", _
                                "August", _
                                "September", _
                                "October", _
                                "November", _
                                "December" _
                            })

        txt.AutoCompleteCustomSource = MySource
        txt.AutoCompleteMode = AutoCompleteMode.Suggest
        txt.AutoCompleteSource = AutoCompleteSource.CustomSource

        AddHandler txt.KeyDown, AddressOf EditControl_KeyDown
    End Sub

    Private Sub EditControl_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
        MsgBox(e.KeyCode)
    End Sub
End Class

Open in new window

Avatar of koossa

ASKER

The EditControl_KeyDown get triggered too late (after the DataGridView1_EditingControlShowing)
I want to get the text value to filter my autocomplete list inside the DataGridView1_EditingControlShowing event.
You do realize that your statement doesn't make much sense, right? How can the KeyDown event be too late to see the text going into the TextBox? The KeyDown event fires each time a key is pressed.

Aside from that, it's still not clear what you are trying to accomplish. An AutoComplete filters its content as one types. How is your filtering different than the built-in functionality?
Avatar of koossa

ASKER

Ok, sorry about that

I've got a database with millions of records, and i'm looking for the fastest way to do it.
What I want to do is as the user type eg 'a' in the grid, I want query the database to only get the items beginning with 'a' and put it in the auto-complete list, because to fill the auto-complete list with millions of records would just be too slow.
That is why I want to get the text value in the DataGridView1_EditingControlShowing event.

Take a look at my code, and put a breakpoint on
Private Function CompileList and see what the value of sText is, then you would probably see what I mean.

Public Class Form1
  Private m_sText As String = ""
  Private m_iSelStart As Integer

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    For i = 1 To 10
      DataGridView1.Columns.Add("Col" & i, "Col" & i)
    Next
    For i = 1 To 10
      DataGridView1.Rows.Add()
    Next
  End Sub

  Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    Dim txt As DataGridViewTextBoxEditingControl
    txt = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
    AddHandler txt.KeyPress, AddressOf EditControl_KeyPress
    AddHandler txt.KeyDown, AddressOf EditControl_KeyDown
    Dim MySource As New AutoCompleteStringCollection()
    MySource.AddRange(CompileList(DataGridView1.CurrentCell.ColumnIndex, m_sText))
    txt.AutoCompleteCustomSource = MySource
    txt.AutoCompleteMode = AutoCompleteMode.Suggest
    txt.AutoCompleteSource = AutoCompleteSource.CustomSource
  End Sub

  Private Sub EditControl_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If m_iSelStart = 0 Then
      m_sText = e.KeyChar & Mid(m_sText, 1, Len(m_sText))
    Else
      m_sText = Mid(m_sText, 1, m_iSelStart) & e.KeyChar & Mid(m_sText, m_iSelStart + 1, Len(m_sText))
    End If
    m_iSelStart += 1
    If m_iSelStart > Len(m_sText) Then
      m_iSelStart = Len(m_sText)
    End If
    Me.Text = m_sText
  End Sub

  Private Sub EditControl_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
    If e.KeyCode = Keys.Left Then
      m_iSelStart -= 1
      If m_iSelStart < 0 Then
        m_iSelStart = 0
      End If
    ElseIf e.KeyCode = Keys.Right Then
      m_iSelStart += 1
      If m_iSelStart > Len(m_sText) Then
        m_iSelStart = Len(m_sText)
      End If
    ElseIf e.KeyCode = Keys.Home Then
      m_iSelStart = 0
    ElseIf e.KeyCode = Keys.End Then
      m_iSelStart = Len(m_sText)
    End If
  End Sub

  Private Function CompileList(ByVal iCol As Integer, ByVal sText As String) As String()
    If sText = "a" Then
      CompileList = Split("BB|CC|DD|EE|FF", "|")
    Else
      CompileList = Split("AA|BB|CC|DD|EE|FF", "|")
    End If
  End Function

End Class

Open in new window

What I want to do is as the user type eg 'a' in the grid, I want query the database to only get the items beginning with 'a' and put it in the auto-complete list, because to fill the auto-complete list with millions of records would just be too slow.

Imagine that the users types 'autocomplete' ... it will try to pull information from a database with millions of records 12 times.

You should use a timer to wait until he/she stops to write and then pull the values.
...or only query after a certain number of characters (e.g. 3 or 4).
Avatar of koossa

ASKER


Imagine that the users types 'autocomplete' ... it will try to pull information from a database with millions of records 12 times.

I don't think I will pull it 12 times from the database. When he enters the first character 'a' I will already get all the words starting with a from the database (including the full word 'autocomplete') and will in other words only populate it when he enters a new start character.

So I think I will just monitor the first character entered.

But my question is still how do I get the character that the user enters in the grid?