Results 1 to 19 of 19

Thread: RESOLVED - Disable some items in a combobox

  1. #1

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    RESOLVED - Disable some items in a combobox

    Hi,

    Is it possible to disable some items in a combobox?
    Depending on the current mode that my application is in, certain items need to be enabled or disabled.
    I know that I could remove the items and rebuild the combobox but in this case I think that by showing the items greyed out it gives the user feedback as to what mode they are in and what options would be available to them if they decided to switch modes.

    Any help appreciated.
    Last edited by A.P.Gumby; Jan 27th, 2009 at 11:46 AM. Reason: Resolved
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  2. #2
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: Disable some items in a combobox

    You don't need to remove the items so much as filter them out. If you bind your combobox to a table for example, you can include a field that indicates what mode (modes) each item is meant for. Then simply filter.

  3. #3

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: Disable some items in a combobox

    Thanks for the quick reply
    Either I didn't explain myself very well or I do not understand your reply. Probably the latter.

    Say I have a combobox with the following items in it
    Apple
    Orange
    Pear
    Dog
    Cat
    Cow

    Depending on the mode that the user has selected elsewhere in the program I want to allow them to select certain items from the combobox.
    In "fruits" mode they can select Apple, Orange or Pear. In "animals" mode they can select Dog, Cat or Cow. In "All" mode they can select any of the items from the combobox.
    But, so that they can see what they are missing when in "fruits" mode, I want to display the animal names grayed out in the combobox.
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  4. #4
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Disable some items in a combobox

    The only way I can think of is if you draw the items yourself by changing the DrawMode property of the combobox to OwnerFixed or OwnerVariable (not sure what the difference is, can someone confirm?) and then use your own DrawItem event handler like this:
    vb.net Code:
    1. 'Declared at class level so it can be used in mutliple procedures
    2. Dim DisabledList As New List(Of String)
    3.  
    4.  
    5. 'Here is our form load event, I'm just adding an item to the list of disabled items here
    6. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    7.         DisabledList.Add("number 1")
    8. End Sub
    9.  
    10. 'Here is the event that actually draws each item
    11. Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ComboBox1.DrawItem
    12.        'Create our font that will be used for drawing each item
    13.         Dim ItemFont As New Font("Arial", 8, FontStyle.Regular)
    14.         'This DirectCast is not completely necessary but it makes it easier to work with the current item we are drawing
    15.         Dim CurrentItem As String = DirectCast(sender, ComboBox).Items(e.Index)
    16.  
    17.         'Draw the background for the item
    18.         e.Graphics.FillRectangle(New SolidBrush(Color.White), e.Bounds)
    19.         'If the item is in the disabled list then we draw the item with a Gray brush
    20.         If DisabledList.Contains(CurrentItem) Then
    21.             e.Graphics.DrawString(CurrentItem, ItemFont, New SolidBrush(Color.Gray), e.Bounds.X, e.Bounds.Y)
    22.         Else
    23.             'The item was not in the disabled list so we draw it with a black brush as normal
    24.             e.Graphics.DrawString(CurrentItem, ItemFont, Brushes.Black, e.Bounds.X, e.Bounds.Y)
    25.         End If
    26.  
    27. End Sub
    Obviously that code still leaves a lot to be desired (the blue background that should appear when the mouse goes over each item doesnt work using my example above) but hopefully you get the idea
    Basically in the draw routine it checks to see if the item is in the DisabledList list and if so then it uses a gray coloured brush to create the text, if not then it uses a black brush. So the idea being that when you want to 'disable' an item you just add it to the DisabledList list.
    Note that this assumes you are just populating the combobox with strings and not classes that override the ToString method (I've never tried that with a combobox but i assume it can be done)

    Hope that helps!
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  5. #5
    PowerPoster JuggaloBrotha's Avatar
    Join Date
    Sep 2005
    Location
    Lansing, MI; USA
    Posts
    4,286

    Re: Disable some items in a combobox

    Quote Originally Posted by chris128
    The only way I can think of is if you draw the items yourself by changing the DrawMode property of the combobox to OwnerFixed or OwnerVariable (not sure what the difference is, can someone confirm?) and then use your own DrawItem event handler like this:
    vb.net Code:
    1. 'Declared at class level so it can be used in mutliple procedures
    2. Dim DisabledList As New List(Of String)
    3.  
    4.  
    5. 'Here is our form load event, I'm just adding an item to the list of disabled items here
    6. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    7.         DisabledList.Add("number 1")
    8. End Sub
    9.  
    10. 'Here is the event that actually draws each item
    11. Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ComboBox1.DrawItem
    12.        'Create our font that will be used for drawing each item
    13.         Dim ItemFont As New Font("Arial", 8, FontStyle.Regular)
    14.         'This DirectCast is not completely necessary but it makes it easier to work with the current item we are drawing
    15.         Dim CurrentItem As String = DirectCast(sender, ComboBox).Items(e.Index)
    16.  
    17.         'Draw the background for the item
    18.         e.Graphics.FillRectangle(New SolidBrush(Color.White), e.Bounds)
    19.         'If the item is in the disabled list then we draw the item with a Gray brush
    20.         If DisabledList.Contains(CurrentItem) Then
    21.             e.Graphics.DrawString(CurrentItem, ItemFont, New SolidBrush(Color.Gray), e.Bounds.X, e.Bounds.Y)
    22.         Else
    23.             'The item was not in the disabled list so we draw it with a black brush as normal
    24.             e.Graphics.DrawString(CurrentItem, ItemFont, Brushes.Black, e.Bounds.X, e.Bounds.Y)
    25.         End If
    26.  
    27. End Sub
    Obviously that code still leaves a lot to be desired (the blue background that should appear when the mouse goes over each item doesnt work using my example above) but hopefully you get the idea
    Basically in the draw routine it checks to see if the item is in the DisabledList list and if so then it uses a gray coloured brush to create the text, if not then it uses a black brush. So the idea being that when you want to 'disable' an item you just add it to the DisabledList list.
    Note that this assumes you are just populating the combobox with strings and not classes that override the ToString method (I've never tried that with a combobox but i assume it can be done)

    Hope that helps!
    When you create a new brush, be sure to clean up the resources so errors don't happen:
    Code:
          'Declared at class level so it can be used in mutliple procedures
          Dim DisabledList As New List(Of String)
    
          'Here is our form load event, I'm just adding an item to the list of disabled items here
          Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                  DisabledList.Add("number 1")
          End Sub
    
          'Here is the event that actually draws each item
          Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ComboBox1.DrawItem
                 'Create our font that will be used for drawing each item
                  Dim ItemFont As New Font("Arial", 8, FontStyle.Regular)
                  'This DirectCast is not completely necessary but it makes it easier to work with the current item we are drawing
                  Dim CurrentItem As String = DirectCast(sender, ComboBox).Items(e.Index)
    
                  'Draw the background for the item
                  Using w As New SolidBrush(Color.White)
                      e.Graphics.FillRectangle(w, e.Bounds)
                  End Using
    
                  'If the item is in the disabled list then we draw the item with a Gray brush
                  If DisabledList.Contains(CurrentItem) Then
                      Using b As New SolidBrush(Color.Gray)
                          e.Graphics.DrawString(CurrentItem, ItemFont, b, e.Bounds.X, e.Bounds.Y)
                      End Using
                  Else
                      'The item was not in the disabled list so we draw it with a black brush as normal
                      e.Graphics.DrawString(CurrentItem, ItemFont, Brushes.Black, e.Bounds.X, e.Bounds.Y)
                  End If 
          End Sub
    Currently using VS 2015 Enterprise on Win10 Enterprise x64.

    CodeBank: All ThreadsColors ComboBoxFading & Gradient FormMoveItemListBox/MoveItemListViewMultilineListBoxMenuButtonToolStripCheckBoxStart with Windows

  6. #6
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Disable some items in a combobox

    Thanks for the tip
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  7. #7

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: Disable some items in a combobox

    Many thanks to all who have contributed.
    That looks like it should work very nicely for me.
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  8. #8
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: RESOLVED - Disable some items in a combobox

    No problem
    If you do need to make it so that the highlight box appears when the user's mouse goes over each item I think you need to do something with the e.DrawFocusRectangle method inside the DrawItem event handler but I've not tested it.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  9. #9
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: RESOLVED - Disable some items in a combobox

    instead of creating a font in the drawitem handler, I would use ComboBox1.font instead. Otherwise the font selection you make at design time will have no effect on the combobox.

  10. #10

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: RESOLVED - Disable some items in a combobox

    Good point!
    Thanks for the suggestion.
    I just need to get the mouseover highlight working and I am there.
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  11. #11
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: RESOLVED - Disable some items in a combobox

    Damn there's always something wrong with my code examples! :P
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  12. #12

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: RESOLVED - Disable some items in a combobox

    That was certainly not meant to be a criticism.
    I always rate helpful posts and yours, and others who assisted me here, were helpful.
    Mind you, if you do come up with a solution to the highlight problem I would appreciate that also
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  13. #13
    PowerPoster JuggaloBrotha's Avatar
    Join Date
    Sep 2005
    Location
    Lansing, MI; USA
    Posts
    4,286

    Re: RESOLVED - Disable some items in a combobox

    This might help:
    Code:
                Dim br As Brush = Brushes.White
                ' change brush color if item is selected
                If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                    br = Brushes.White
                Else
                    br = Brushes.Black
                End If
    You'd use code similar to that when drawing the background for the current item
    Currently using VS 2015 Enterprise on Win10 Enterprise x64.

    CodeBank: All ThreadsColors ComboBoxFading & Gradient FormMoveItemListBox/MoveItemListViewMultilineListBoxMenuButtonToolStripCheckBoxStart with Windows

  14. #14

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: RESOLVED - Disable some items in a combobox

    Thanks, I'll give that a go.
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  15. #15
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: RESOLVED - Disable some items in a combobox

    I would wrap this up in a class to make it easier to work with and modify.

    If you add a new class and add in this code, you can then use ComboBoxEx from the toolbox instead of using a regular combobox and having to add all this code to your form.

    Also, this will expose the DisabledItems property in the property grid, so you can easily add items at design time that you want to be grayed out.

    Code:
    Imports System.ComponentModel
    
    Public Class ComboBoxEx
        Inherits ComboBox
    
        Private _DisabledItems As New List(Of String)
    
    
        Public Sub New()
            Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
        End Sub
    
    
        Private Function IsItemDisabled(ByVal Index As Integer) As Boolean
            Return _DisabledItems.Contains(Me.Items(Index).ToString)
        End Function
    
        Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
            Dim TextToDraw As String = Me.Items(e.Index).ToString
    
            e.DrawBackground()
            e.DrawFocusRectangle()
    
            'If the item is in the disabled list then we draw the item with a Gray brush
            If IsItemDisabled(e.Index) Then
                Using b As New SolidBrush(Color.Gray)
                    e.Graphics.DrawString(TextToDraw, Me.Font, b, e.Bounds.X, e.Bounds.Y)
                End Using
            Else
                Using b As New SolidBrush(e.ForeColor)
                    e.Graphics.DrawString(TextToDraw, Me.Font, b, e.Bounds.X, e.Bounds.Y)
                End Using
            End If
    
            MyBase.OnDrawItem(e)
        End Sub
    
        <Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")> _
        Public Property DisabledItems() As List(Of String)
            Get
                Return _DisabledItems
            End Get
            Set(ByVal value As List(Of String))
                _DisabledItems = value
            End Set
        End Property
    
    End Class

  16. #16

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: RESOLVED - Disable some items in a combobox

    That works very well - Thank You

    The only remaining issue that I have is stopping the user from selecting the disabled items.
    The way that I have implemented at the moment is to do a check in the SelectedIndexChanged event to see if the user has clicked on a disabled item. If they have then I just increment the SelectedIndex value.
    This works but is not as elegant as I would like.
    I have found some complicated C# code that intercepts the highlight changed but do not know where to start with converting it to VB.
    Any ideas?
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  17. #17
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: RESOLVED - Disable some items in a combobox

    To do that, you will probably want to handle some key press events to, because you will want to know if the user is scrolling the list with arrow keys, up or down so you can jump the disabled items in the correct direction.

  18. #18

    Thread Starter
    Addicted Member A.P.Gumby's Avatar
    Join Date
    Oct 2005
    Location
    Outside the assylum
    Posts
    147

    Re: RESOLVED - Disable some items in a combobox

    Thanks for the advice.
    Using Visual Studio 2008.
    I am not young enough to know everything - Oscar Wilde

  19. #19
    New Member
    Join Date
    Sep 2013
    Posts
    1

    Re: RESOLVED - Disable some items in a combobox

    kleinma,

    I have then ComboBoxEx working, but I am having trouble creating a DLL with VB 2010. Is this caused by 2010 and not having 2008? Any help would be appreciated

Posting Permissions

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



Click Here to Expand Forum to Full Width