Link to home
Start Free TrialLog in
Avatar of fesit
fesit

asked on

VB.NET Datagridview - capture DataGridViewCheckBoxColumn click event

VB.NET - Datagridview - Capture CheckBoxColumn click...

Hello.  I seem to be having a bit of a problem programming in VB.NET 2005.
I have a form.  On that form I have a datagridview control.  One of those columns I defined as a DataGridViewCheckBoxColumn.
I cannot figure out how to capture when the user checks/unchecks the button.
For instance, once the cell has focus.  Already passed by the CellBeginEdit and all that stuff...  If the user just sits there for 20 minutes doing nothing but checking and unchecking the check box, I cannot capture it.  The CellEndEdit does not capture it.  Neither does the CellValueChanged.  Or the CurrentCellDirtyStateChanged.  Or the CellClick.  
Is there any way to capture the click even AS is it occurring?  So I do not have to wait for the cell to lose focus?  
How can I accses the checkbox itself?  Is there a way to do that?  To access a checkbox inside of a datagridview?

I appreciate all of your help in advance....

Jae
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Jae,

One way is to attach an event handler to the editing control in the EditingControlShowing event handler:

If TypeOf e.Control Is CheckBox Then
   AddHandler CType(e.Control, CheckBox).CheckedChanged, AddressOf OnCheckBoxChanged
End If

Bob
You can do it using the CellClick Event

Private Sub MyDataGridView_CellClick(...) ...

If MyDataGridView.Column(e.ColumnIndex).NAme = "MyColumn" Then
  ' Your code
End If

End Sub
Avatar of fesit
fesit

ASKER

TheLearnedOne,
I am a little confused - I tried to copy your code into my grdview_EditingControlShowing method and i get a syntax error at the "OnCheckBoxChanged" - says it is not defined.
Also, if that did work, once the handler is added, how/where do you reference it?
Thanks...

Jae
Avatar of fesit

ASKER

JPaulino,

Hi.  
Ok, so you're code worked...in a way.
It catches the click - but I cannot get the value of the checkbox -
Here is my code:

    Private Sub grdAddEnt_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdAddEnt.CellClick
        If grdAddEnt.Columns(e.ColumnIndex).Name = "coAddEntAdd" Then
            MessageBox.Show("CellClickWorked")
            MessageBox.Show(grdAddEnt.Rows(e.RowIndex).Cells("coAddEntAdd").Value.ToString)

        End If
    End Sub

When it tries to display the 2nd messagebox, I get this error "Object reference not set to an instance of an object."
If I check the value of "grdAddEnt.Rows(e.RowIndex).Cells("coAddEntAdd").Value.ToString" in the Immediate Window, I get "Reference object has a value of 'Nothing'."

Any idea how to catch the value/state of the checkbox once your code catches the click itself?

Thank you....

Jae

SOLUTION
Avatar of Priest04
Priest04
Flag of Serbia 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
If you cant convert the code to VB.NET, please let me know, and I will convert it form you. Here is also a useful link for converting the code

http://www.developerfusion.co.uk/utilities/convertvbtocsharp.aspx

Goran
ASKER CERTIFIED 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
You need to add the event handler:

Private Sub OnCheckBoxChanged(ByVal sender As Object, ByVal e As EventArgs)
End Sub

Bob
Avatar of fesit

ASKER

JPaulino,
Your code seemed to work for the most part - but I found one issue.
Basically, it gives me the value before it is checked/unchecked, so i just need to take the opposite value.  If it is being checked, it reads false, so I know it's being changed to true.  Thats fine.
The problem that I came across is if the user clicks in the checkbox cell without clicking the checkbox itself.  
If the checkbox was unchecked as I entered the cell, and I clicked in the CELL (but not the checkbox itself), I will still get the "False" value returned (as it would be in the process of being checked, normally) - but if i took the opposite of that "False" reading, assuming it was going to be checked, and now I said that the value is "True" - if they only clicked in the cell WITHOUT clicking IN the checkbox itself, it would still be reading "False", and the checkbox would not be checked.
Not sure if I explained that clearly - does it make sense?





TheLearnedOne,
So I have this code in the EditingControlShowing of the datagridview
    Private Sub grdAddEnt_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles grdAddEnt.EditingControlShowing
        If TypeOf e.Control Is CheckBox Then
            AddHandler CType(e.Control, CheckBox).CheckedChanged, AddressOf OnCheckBoxChanged
        End If
    End Sub

and i added this sub
    Private Sub OnCheckBoxChanged(ByVal sender As Object, ByVal e As EventArgs)
        MessageBox.Show("OnCheckBoxChanged")
    End Sub

This code never gets hit when i check the checkbox in that column.  if i start to edit a text column, then the EditingControlShowing gets hit, but not for the checkboxes.






I think I may have found a way that works, combining part of what JPaulino said, and part trial and error on my part, and part Priest04.  
If I use JPaulino's code in the CellContentClick event that Priest mentioned, it seems to work.
I need to do some more testing.
Avatar of fesit

ASKER

After some further testing, that combination of code seems to work.

Thank you all for your prompt replies and your help.

Since you have picked jpaulino's solution, then you need one thing to correct: you don't need to create instance of DataGridViewCheckBoxCell, since you are not using it anywhere in your code

So, instead of

Dim dgCB As New DataGridViewCheckBoxCell

it should be

Dim dgCB As DataGridViewCheckBoxCell

Goran
Avatar of fesit

ASKER

Priest04 -

I am using it in the code....
Here is what the final code that I'm using looks like:

    Private Sub grdEntEnts_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdEntEnts.CellContentClick

        If CType(sender, DataGridView).Columns(e.ColumnIndex).Name = "coEntEntsRemove" Then

            Dim dgCB As New DataGridViewCheckBoxCell
            dgCB = CType(grdEntEnts("coEntEntsRemove", e.RowIndex), DataGridViewCheckBoxCell)
            If CBool(dgCB.EditedFormattedValue) Then
                DeleteEntEnts(CType(sender, DataGridView), e.RowIndex)
            Else
                AddEntEnts(CType(sender, DataGridView), e.RowIndex)
            End If

        End If
    End Sub
AS I have said

remove the New keyword, it is not needed. It should be

Dim dgCB As DataGridViewCheckBoxCell

Goran
Avatar of fesit

ASKER

Ok Goran,

I have done AS you have said.
I guess I just misunderstood you being that you said I was not using it anywhere in my code when it was in my code.

My appologies.

We need to look after the memory resources whenever we can. ;)

Goran