Welcome to WindowsClient.net | Sign in | Join

Here are some frequently asked questions about Windows Forms and their answers.

Windows Forms FAQs

Why does the CheckedListBox lose checked state when placed in a tab page that gets hidden and shown?

In Usenet posts, MS has acknowledged this bug. The problem is essentially that any time the visibility changes on a CheckedListBox, it loses its previous selections. Naturally this happens all the time in tab controls when changing tabs. This derived Control saves its state while getting hidden and reloads it while getting shown:

When CheckedList box becomes invisible (e.g. when the tab page containing this control is overlapped with another tab page), checked state of the items are getting lost. This workaround will fix this problem.

[C#]

private bool[] isItemChecked;

protected override void OnDataSourceChanged( EventArgs e )
{
  base.OnDataSourceChanged( e );
  int cnt = Items.Count;
  isItemChecked = new Boolean[ cnt ];
  for( int i = 0; i < cnt; ++i )
    isItemChecked[ i ] = GetItemChecked( i );
}

protected override void OnItemCheck( ItemCheckEventArgs e )
{
  base.OnItemCheck( e );
  isItemChecked[ e.Index ] = ( e.NewValue == CheckState.Checked );
}

protected override void OnVisibleChanged( EventArgs e )
{
  base.OnVisibleChanged( e );
  if ( Visible == true ) // reset checked states when it becomes visible
    for( int i = 0; i <  Items.Count; ++i )
      SetItemChecked( i, isItemChecked[ i ] );
  }
}

[Visual Basic]

Public Class MyCheckedListBox
  Inherits CheckedListBox

  Private isItemChecked() As Boolean

  Protected Overrides Sub OnDataSourceChanged(ByVal e As EventArgs)
    MyBase.OnDataSourceChanged(e)
    Dim cnt As Integer = Items.Count
    isItemChecked = New [Boolean](cnt) {}
    Dim i As Integer
    For i = 0 To cnt - 1
      isItemChecked(i) = GetItemChecked(i)
    Next i
  End Sub

  Protected Overrides Sub OnItemCheck(ByVal e As ItemCheckEventArgs)
    MyBase.OnItemCheck(e)
    isItemChecked(e.Index) = e.NewValue = CheckState.Checked
  End Sub

  Protected Overrides Sub OnVisibleChanged(ByVal e As EventArgs)
    MyBase.OnVisibleChanged(e)
    If Me.Visible = True Then ' reset checked states when it becomes visible
      Dim i As Integer
      For i = 0 To Items.Count - 1
        SetItemChecked(i, isItemChecked(i))
      Next i
    End If
  End Sub

End Class

Eric and Reddy Duggempudi