Question Key Down not working in Datagridview

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
Hi,

I am trying to capture a key down (or key press or key up) as I want to count the number of characters in a cell and let the user know how may the have left. The datagridview is tied to a dataset and the column has a max 200 character limit in the database, thus once they go above this the whole row is deleted by the datagridview!

So far I have worked out that I need to add an event handler to the column/cells in question and I have got so far, but it still does not update the total number of characters after each key down !!!

VB.NET:
 Private Sub DataGridView1_EditingControlShowing(sender As System.Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    'Add handler for columns 3 and 4       
    If Me.DataGridView1.CurrentCell.ColumnIndex > 2 And Me.DataGridView1.CurrentCell.ColumnIndex < 5 Then
               AddHandler e.Control.KeyDown, AddressOf Cell_KeyDown
    End If
End Sub


    Private Sub Cell_KeyDown(sender As Object, e As KeyPressEventArgs)
       'Recalc number of chars left
        Dim CellText As String = ""
        CellText = Me.DataGridView1.CurrentCell.Value.ToString
        lCharCount.Text = (200 - CellText.Length) & " Chars Left!"
        If CellText.Length > 199 Then
            MessageBox.Show("Too many characters, 200 max!", "HCS - Alert!")
        End If


    End Sub

Any idaes where I am going wrong ?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,745
Location
Sydney, Australia
Programming Experience
10+
Wouldn't it make more sense to handle the TextChanged event? Also, the whole point of handling the event of the editing control is that it's the editing control that's changing, NOT the grid cell. The editing control is a TextBox and all you care about is the TextLength of that TextBox when its Text changes, so that's what you should be using.

Also, you should be handling the CellEndEdit event of the grid and removing that event handler that you added. Any time you use AddHandler, you should be using RemoveHandler too.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
Hi Jimmy,

Thats definitely helped, it is now showing the correct letter count, but it only updates the letter count when I leave the cell and re enter it!

Is there any way of maing it smoother by happening as I type?

Here my new code
 Private Sub DataGridView1_EditingControlShowing(sender As System.Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
        If Me.DataGridView1.CurrentCell.ColumnIndex > 2 And Me.DataGridView1.CurrentCell.ColumnIndex < 5 Then
             AddHandler e.Control.TextChanged, AddressOf Cell_TextChanged
        End If
    End Sub


    Private Sub Cell_TextChanged() 'sender As Object, e As KeyPressEventArgs
        Dim CellText As String = ""
        CellText = Me.DataGridView1.CurrentCell.Value.ToString
        lCharCount.Text = (200 - CellText.Length) & " Chars Left!"
        If CellText.Length > 199 Then
            MessageBox.Show("Too many characters, 200 max!", "HCS - Alert!")
        End If


    End Sub

 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,745
Location
Sydney, Australia
Programming Experience
10+
I specifically said this:
Also, the whole point of handling the event of the editing control is that it's the editing control that's changing, NOT the grid cell. The editing control is a TextBox and all you care about is the TextLength of that TextBox when its Text changes, so that's what you should be using.
Where in your code are you using the TextLength of the TextBox like I SPECIFICALLY told you to do? You're not. Instead, you're using the grid cell rather than the TextBox, which I SPECIFICALLY told you not to do. What part of "NOT the grid cell" is confusing?
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
Can you point me to a worked example. I did see one where the cell is recast as a textbox, is this what you mean?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,745
Location
Sydney, Australia
Programming Experience
10+
How many times do I have to say it? Forget the cell. You have no interest in the cell. The cell is irrelevant. The TextBox is the TextBox and the cell is the cell. They are two completely different things. You care about the TextBox. You don't care about the cell.

Why do you need me to point you to an example? Are you not capable of searching the web for some reason? I just searched for "vb.net handle textchanged event of textbox in datagridview" and I was looking at an example 10 seconds later. If I can do that, why can't you?

You probably think I'm being hard on you but I gave you all the information you needed six days ago and we're still going over the same stuff. I'm not here to give people code that they can blindly copy and paste and learn nothing from. I expect people to think. I told you to begin with that you're not interested in the cell and you're still asking about the cell. What I expect is that, when I provide people with keywords relating to their issue, they will use those keywords to find more information if they need it. The search that I just did contains only obvious keywords. There's nothing obscure in there so there is absolutely no excuse for your not having done the same search for yourself. If you can't search the web then you're not capable of programming. If you think you are capable of programming - and I think you are - then you must be capable of performing a simple web search to... so do it.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
Jimmy,

I thought this site was about providing support to vb users, not referring them onto other sites to find the answers. While I appreciate it must be extremely frustrating when a member doesn't see things as clearly as you do, but sarcasm doesn't help, it only provides momentary relief to your frustration!

I have looked through the web before posting on this forum, several times in fact and I have not found an example that clearly explains whats going with events controls, datagridview, cells and textboxes you keep referring too.

I have seen your sarcastic and belittling comments to other members too and it does not promote ethos a community of forum, which is a shame because it is an excellent forum, but anyone reading your reactions will undoubtedly be searching the internet rather than having the temerity of asking a question on this forum.

When I have to explain something to someone who has difficulty understanding I try to go slowly and take time to explain it as detailed as possible, taking time, going slowly, asking people to search the internet is not really helping explain a difficult area.

Have you ever though of taking a break and let someone else do the answering, perhaps your burned out or its not just a job your suited too, unfortunately in life we don't always get to work with the geniuses you'd like, sometimes you have to work with ordinary people too.

kind regards
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,609
Location
Norway
Programming Experience
10+
You need the 'sender' parameter of the TextChanged event handler:
Dim box = CType(sender, TextBox)
If box.TextLength > 200 ...
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,609
Location
Norway
Programming Experience
10+
You can also simplify things with adding/removing event handlers by assigning the editing control to a WithEvents variable. If all these editing controls are textboxes you can do this:
Private WithEvents CellEditBox As TextBox

Then in EditingControlShowing handler:
CellEditBox = CType(e.Control, TextBox)

You can select CellEditBox and its events in code editor as other controls and have IDE generate the event handlers, or write them yourself and add the Handles clause manually. For example selecting TextChanged event will generate this code:
Private Sub CellEditBox_TextChanged(sender As Object, e As EventArgs) Handles CellEditBox.TextChanged

End Sub
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,745
Location
Sydney, Australia
Programming Experience
10+
I thought this site was about providing support to vb users, not referring them onto other sites to find the answers.
This site is about helping people solve their VB.NET programming issues. That doesn't necessarily mean writing their code for them. Providing the keywords people need to find existing information elsewhere is a perfectly legitimate way of helping someone. There's really no point reproducing information here that can be found easily elsewhere if you know what to look for. I told you what to look for but you need to be prepared to look.
While I appreciate it must be extremely frustrating when a member doesn't see things as clearly as you do, but sarcasm doesn't help, it only provides momentary relief to your frustration!
Actually, sarcasm does help in many cases. If someone does something they shouldn't and noone calls them out on it, they'll likely do the same thing again. If they are made to feel foolish for doing so then the next time they may reconsider doing the same thing for fear of being made to feel foolish again. Negative reinforcement works and has its place.
I have looked through the web before posting on this forum
But you didn't necessarily know what to look for. I gave you new information that you were supposed to use to but you didn't. That's my issue. You asked for help and, when it was provided, you ignored it. You expected someone else to write your code for you and, when they didn't, you sat on your hands instead of engaging your brain. The search I said that I performed in post #8 was done with information that you didn't have originally but that I provided to you. If you'd used that information then you could have found everything you needed but you didn't bother.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
HI JohnH, Thank you so much for your posting, your answer was sublime!
You can also simplify things with adding/removing event handlers.....
Private WithEvents CellEditBox As TextBox

Then in EditingControlShowing handler:
CellEditBox = CType(e.Control, TextBox)

You can select CellEditBox and its events in code editor..... selecting TextChanged event will generate this code:
Private Sub CellEditBox_TextChanged(sender As Object, e As EventArgs) Handles CellEditBox.TextChanged
...
End Sub

Brillaint,

Here is my finished code below and it work a treat! including giving the user a visual count down....

VB.NET:
Private Sub DataGridView1_EditingControlShowing(sender As System.Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
        If Me.DataGridView1.CurrentCell.ColumnIndex > 2 And Me.DataGridView1.CurrentCell.ColumnIndex < 5 Then
            CellEditBox = CType(e.Control, TextBox)
       End If
    End Sub


    Private Sub CellEditBox_TextChanged(sender As Object, e As EventArgs) Handles CellEditBox.TextChanged
        ' MsgBox("OK1")
        lCharCount.Text = (200 - CellEditBox.TextLength) & " Chars Left!"
        If CellEditBox.TextLength > 199 Then
            MessageBox.Show("Too many characters, 200 max!", "HCS - Alert!")
            CellEditBox.Text = CellEditBox.Text.Substring(0, 199)
        End If
    End Sub

Look how much simpler this code is !

Can I ask though do I still need to remove an event ? or destroy the CellEditBox in some way!
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,609
Location
Norway
Programming Experience
10+
Can I ask though do I still need to remove an event ? or destroy the CellEditBox in some way!
No, you don't. The edit box lives at most as long as form it is in. DGV control manages the editing control internally.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,745
Location
Sydney, Australia
Programming Experience
10+
HI JohnH, Thank you so much for your posting, your answer was sublime!


Brillaint,

Here is my finished code below and it work a treat! including giving the user a visual count down....

VB.NET:
Private Sub DataGridView1_EditingControlShowing(sender As System.Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
        If Me.DataGridView1.CurrentCell.ColumnIndex > 2 And Me.DataGridView1.CurrentCell.ColumnIndex < 5 Then
            CellEditBox = CType(e.Control, TextBox)
       End If
    End Sub


    Private Sub CellEditBox_TextChanged(sender As Object, e As EventArgs) Handles CellEditBox.TextChanged
        ' MsgBox("OK1")
        lCharCount.Text = (200 - CellEditBox.TextLength) & " Chars Left!"
        If CellEditBox.TextLength > 199 Then
            MessageBox.Show("Too many characters, 200 max!", "HCS - Alert!")
            CellEditBox.Text = CellEditBox.Text.Substring(0, 199)
        End If
    End Sub

Look how much simpler this code is !

Can I ask though do I still need to remove an event ? or destroy the CellEditBox in some way!

If you use AddHandler to attach an event handler then you do need to use RemoveHandler to detach it. If you use WithEvents on a field and Handles on a method then the event handler is attached to the variable so the event handler is automatically detached from the previous object when you assign a new object to that variable. The grid manages the lifetime of the editing control. It will reuse a control if you edit two cells of the same type in succession, otherwise it will destroy a control after an editing session and create another one as needed.
 
Top Bottom