views:

191

answers:

2

I am trying to figure out how to set the value of the text that is displayed for each item of a list control, such as a checkbox list, but really this applies to most list controls, not just the checklistbox control.

I have a checklistbox control:

    Friend WithEvents clstTasks As System.Windows.Forms.CheckedListBox

...that I usually want to populate with a list of task names. I call the add method to add a Task object to the list. I know that if I override the ToString method, whatever value is returned by that function will be displayed as the text for the list item.

However, in rare situations, I want to display something else other than just the name. For example, perhaps I want to display the name and the value of another property, such as the value of the Boolean property "Optional" shown in parenthesis following the name.

What is the best way to do this?

The best that I can think of is to define a property which is set in the GUI layer and then used by the ToString function to determine how it should behave when called. If the controlling property is set to one value, the ToString will return the Name, else it will return the Name followed by the value of the Optional flag. This seems a little disjoint a kludged to me.

The other alternative which seems a little overkill is to define a new class which inherits from Task, for example TaskOptional, which overrides the Tostring method on the base class. In this subclass, the ToString function would return the Name/Optional flag value. However, this, too, seems a little nuts to have to come up with a new class just to modify how the text is being displayed in the presentation layer. I feel that I should be able to control this in the presentation layer w/o chging the business object or creating a new derived object.

What is the best way to accomplish this?

    For Each CurrentTask As Task In _MasterTaskList
        clstTasks.Items.Add(CurrentTask, True)
    Next

    Public Class Task

       Private _Name As String
       Private _Optional As Boolean

       Public Sub New (name As String, optional As Boolean)
           _Name = name
       End Sub

       Public Overrides Function ToString() As String
             Return _Name
          End If
      End Function

    End Class
+1  A: 

You could do the following

Public Overrides Function ToString() As String
   Return string.Format("{0}{1}", _Name, IIF(_Optional, " (Optional)", ""))
End Function

EDIT: You will have to set the value of _optional in the constructor, which is missing in the code you have provided.

shahkalpesh
That's what I expected but didn't really like. I was hoping for an event such as ListItemPreRender where I could set the Text property on a ListItem. It just seemed more appropriate for the text property to be controllable from the list control instead of relying on the class's ToString function.I think I'll add a property which enumerates how the ToString function should behave.Public Property ToStringBehaviour As ToStringBehaviourEnumPublic Enum ToStringBehaviourEnum As Integer DisplayNameOnly DisplayNameAndOptional 'Allow for future variationsEnd Enum
Velika
+2  A: 

You can set the DisplayMember property of your CheckedListBox to the name of one of your custom class' property.

Let's say you create a property like the following:

Public ReadOnly Property NameOptional() As String
  Return _Name & " (" & _Optional & ")"
End Property

then you can set the display member like this:

clstTasks.DisplayMember = "NameOptional"

When you set a display member, this property will be displayed instead of the ToString value.

Meta-Knight
Note that this is a Winform example, not WebForms. There is no DisplayMember property on the CheckList control. I believe you were thinking Web controls.
Velika
MSDN says otherwise...http://msdn.microsoft.com/en-us/library/yx9dzztb.aspxI see that the browsable attribute is set to false, so it's possible that you can't see it in the list of properties, but can still set it in code.
Meta-Knight