Results 1 to 11 of 11

Thread: CheckedListBox's ItemCheck event : bad timing...

  1. #1
    Stonkie is offline VB.NET Forum Master
    .NET Framework
    .NET 2.0 (VS 2005)
    Join Date
    Sep 2007
    Posts
    279
    Reputation
    136

    CheckedListBox's ItemCheck event : bad timing...

    I need to produce a list of checked entries from a CheckedListBox whenever an item changes, but that ItemCheck event gets thrown before the item's status is actually changed so the checked items list is incorrect.

    I found a forum post telling to use the SelectedIndexChanged event instead, but that won't work if the user checks the item using the space bar.

    My two alternatives are to :

    1. Use the ItemCheckEventArgs to figure out what item changed and how. Since the code that gets the list of checked items is a few methods down on the calls hierachy, I would need to pass the event args around (or more likely an homemade representation of its data for consistency).

    2. Use a class member boolean to see if I'm in the ItemCheck event handler and set the item's checked state to its correct value before calling the method that does the processing. The boolean is used to avoid an infinite call of the event handler, it would just return without any processing in the case the event handler is in the call stack itself.

    Anyone knows how to write this in a cleaner fashion?

    Btw, I also tought about inheriting the CheckedListBox control to override the SetCheckedState method, but it is not virtual...
    Last edited by Stonkie; 05-12-2008 at 10:05 AM.
    The human mind's capability to comprehend abstract concepts is limited to the vocabulary it can use to describe it. The more precise the building blocks, the more complex the thoughts that can emerge... Sounds like the evolution of programming languages doesn't it?

  2. #2
    JohnH's Avatar
    JohnH is offline VB.NET Forum Moderator
    .NET Framework
    .NET 4.0
    Join Date
    Dec 2005
    Location
    Norway
    Posts
    14,612
    Reputation
    2739
    The easiest is to get the current selection collection and if NewValue of ItemCheck event is Checked also add this item to the collection, else remove it.

  3. #3
    Stonkie is offline VB.NET Forum Master
    .NET Framework
    .NET 2.0 (VS 2005)
    Join Date
    Sep 2007
    Posts
    279
    Reputation
    136
    Yeah, that's option 1, but the list is created a few method calls further, so I do not have access to the ItemCheckEventArgs directly unless I send the NewValue and changed index through 2 method calls to the point where it is needed... That totally breaks the meaning of the methods...

    Here's the solution I've come up with (option 2). It's a bit of a hack but I think it works well!

    Code:
    private checkingCategory as Boolean = false
    
    private sub chklistCategories_ItemCheck(sender as Object, e as ItemCheckEventArgs) handles chklistCategories.ItemCheck
        if (!checkingCategory) then
            checkingCategory = true
    
            chklistCategories.SetItemCheckState(e.Index, e.NewValue)
            ApplyCategoryChanges()
            
            checkingCategory = false
        end if
    end sub
    I'd be very interested in some cleaner solution in case I need to do this again though!

    Thanks for the input JohnH!

    PS. I translated this from C# pretty fast, the concept is there but the syntax may be broken...
    The human mind's capability to comprehend abstract concepts is limited to the vocabulary it can use to describe it. The more precise the building blocks, the more complex the thoughts that can emerge... Sounds like the evolution of programming languages doesn't it?

  4. #4
    cjard's Avatar
    cjard is offline VB.NET Forum All-Mighty
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2006
    Posts
    7,036
    Reputation
    1722
    You might have more success if you use a datagridview with a checkbox column and a textbox column

  5. #5
    Stonkie is offline VB.NET Forum Master
    .NET Framework
    .NET 2.0 (VS 2005)
    Join Date
    Sep 2007
    Posts
    279
    Reputation
    136
    Yeah, I can customize the DataGridView's appearance to look pretty much the same and I can finally use the DataSource property!

    Thanks!
    The human mind's capability to comprehend abstract concepts is limited to the vocabulary it can use to describe it. The more precise the building blocks, the more complex the thoughts that can emerge... Sounds like the evolution of programming languages doesn't it?

  6. #6
    InertiaM is offline VB.NET Forum Idol
    .NET Framework
    .NET 2.0
    Join Date
    Nov 2007
    Location
    Kent, UK
    Posts
    663
    Reputation
    250
    Just having to do the same as Stonkie, so I'm trying to change a CheckedListBox over to a DataGridView.

    1. I've changed the CellBorderStyle to None, but my rows are still too large. I know I can change the row height, but why does the default row height of a DGV differ from the row height of a CLB given the same font?

    2. Whilst designing the changeover, I had a CLB and DGV on the same form, both bound to the same datatable. When I select a row on the DGV, .NET automatically selects the corresponding item in the CLB. I've never seen this before - is it a *standard* feature for all .NET controls that are bound to a datasource?
    Always parameterize your queries - read more here

    "When people discover the center of the universe, a lot of them will be disappointed to find they are not it."

  7. #7
    cjard's Avatar
    cjard is offline VB.NET Forum All-Mighty
    .NET Framework
    .NET 4.0
    Join Date
    Apr 2006
    Posts
    7,036
    Reputation
    1722
    Quote Originally Posted by InertiaM View Post
    1. I've changed the CellBorderStyle to None, but my rows are still too large. I know I can change the row height, but why does the default row height of a DGV differ from the row height of a CLB given the same font?
    Padding, or margins

    2. Whilst designing the changeover, I had a CLB and DGV on the same form, both bound to the same datatable. When I select a row on the DGV, .NET automatically selects the corresponding item in the CLB. I've never seen this before - is it a *standard* feature for all .NET controls that are bound to a datasource?
    It's a standard notion in the concept of MVC. The dataview or bindingsource maintains knowledge of position within a data model. When one controlling element changes that position, all other bound controls naturally see the change. If youre struggling with the concept, consider a webcam looking at some flowers. Hundreds of people view the cam and they see flowers. Then someone moves the cam to show a bowl of fruit. Now all people viewing the camera see fruit.

  8. #8
    InertiaM is offline VB.NET Forum Idol
    .NET Framework
    .NET 2.0
    Join Date
    Nov 2007
    Location
    Kent, UK
    Posts
    663
    Reputation
    250
    The concept's fine What I was struggling with was unexpected SelectedIndexChanged events on a control that didnt have the focus. I'll be more careful in future
    Always parameterize your queries - read more here

    "When people discover the center of the universe, a lot of them will be disappointed to find they are not it."

  9. #9
    ssimoes is offline VB.NET Forum Newbie
    .NET Framework
    .NET 4.0
    Join Date
    Nov 2011
    Posts
    1
    Reputation
    0
    I don't know if this is yet relevant (at least for me it was) but I believe that you can predict if the item is or not being checked (and act according to this supposition) via the ItemCheck event. For instance:

    Code:
    Private Sub chklist_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles chklist.ItemCheck
    if Not chklist.CheckedItems.Contains(chklist.SelectedItem) then
    'Proceed as with the item is being checked ...
    else
    'Proceed otherwise ...
    end if
    end sub
    Sergio
    Last edited by ssimoes; 11-11-2011 at 2:43 PM.

  10. #10
    GPilotino is offline VB.NET Forum Newbie
    .NET Framework
    .NET 3.5
    Join Date
    Aug 2012
    Posts
    1
    Reputation
    0
    My approach:

    Code:
        Private Sub CheckedListBox1_ItemCheck(sender As Object, e As System.Windows.Forms.ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
            Dim cList As New List(Of String)
            For Each item In CheckedListBox1.CheckedItems
                cList.Add(item)
            Next
    
            If Not cList.Contains(CheckedListBox1.Items(e.Index)) Then
                cList.Add(CheckedListBox1.Items(e.Index))
            ElseIf e.NewValue = CheckState.Unchecked Then
                cList.Remove(CheckedListBox1.Items(e.Index))
            End If
    
            Dim sb As New System.Text.StringBuilder
            For Each i As String In cList
                sb.Append(i)
                sb.Append(" ")
            Next
            MessageBox.Show(sb.ToString(), "Checked Items")
    
    
        End Sub
    Gino.
    Last edited by GPilotino; 08-30-2012 at 5:05 PM.

  11. #11
    KB81861 is offline VB.NET Forum Newbie
    .NET Framework
    .NET 3.5
    Join Date
    Jan 2013
    Posts
    1
    Reputation
    0
    To get a simple count of the number of checked Items, this is how I approached it through the OnItemCheck event:

    Dim checkedCount AsInteger
    If ice.NewValue = CheckState.Checked Then
    checkedCount = Me.CheckedItems.Count + 1
    Else
    checkedCount = Me.CheckedItems.Count - 1
    EndIf

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Harvest time tracking