Browse DevX
Sign up for e-mail newsletters from DevX


Gaining Control of the .NET ListBox : Page 3

Although .NET's Windows Forms ListBox control has extended capabilities, it can be problematic to do some of the simplest things. But by using delegates, you can achieve near-total control.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Delegate Control
At this point, change personas and put on a control creator's hat. Here's a different approach to displaying custom strings based on some object.

Unless there's a good reason not to do so, when you create a class, you typically want the class *consumer* to have as much control over the instantiated objects as possible. One way to increase the class consumers' power is to give them control over the method that the ListBox (or other code) calls to get a string representation of your object. In other words, rather than pre-define multiple display methods within your class, you could provide a public Delegate type and then add a private member variable and a public property to your class that accept that delegate type.

' Public Delegate type definition Public Delegate Function displayPersonDelegate _ (ByVal p as Person) as String ' Private member variable Private mDisplayMethod as displayPersonDelegate ' Public Property Public Property DisplayMethod() as displayPersonDelegate Get Return mDisplayMethod End Get Set (ByVal Value as displayPersonDelegate) mDisplayMethod=Value End Set End Property

In the code above, the displayPersonDelegate accepts a Person object and returns a string. The class consumer will create a displayPersonDelegate object and assign it to the public DisplayMethod property.

Next, override the ToString method so that it returns the delegate result value. For example:

Public Overloads Overrides Function ToString() _ as String ' Check to see if a delegate exists If Me.DisplayMethod is Nothing ' use the default MyBase.ToString, or ' any other default ToString implementation ' you wish Return MyBase.ToString Else ' Try to invoke the assigned delegate Try Return Me.DisplayMethod(Me) Catch ' again, use the default MyBase.ToString, or ' any other default ToString implementation ' you wish Return MyBase.ToString() End Try End Property

The advantage of this scheme is that the object consumer gets the best of both worlds—a default ToString implementation assignable by the class creator and the ability to call a custom ToString method by assigning the delegate. And the class creator doesn't need to worry about all the possible ways that a user may wish to display an object. Finally, it gives the object consumer the ability to set different custom ToString methods for every instance of the Person class.

The simplest way to use the Person class is to assign a collection of them to some collection object, setting the DisplayMethod for each Person to a function matching displayPersonDelegate signature. For example, to create an ArrayList containing the Person objects, you would first write the display functions:

Public Function DisplayPersonFirstLast _ (byVal p as Person) as String Return p.FirstName & " " & p.LastName End Function Public Function DisplayPersonLastFirst _ (byVal p as Person) as String Return p.LastName & ", " & p.FirstName End Function

Next, when you create the collection, you assign the DisplayMethod for each Person object.

' define an ArrayList at class level Private people As New ArrayList() ' create Person objects and add them ' to the people ArrayList Dim p as person p = New Person(1, "Twain", "Mark", "MT") ' create a displayPersonDelegate for the ' DisplayPersonLastFirst method p.DisplayMethod = New Person.displayPersonDelegate _ (AddressOf DisplayPersonLastFirst) people.Add(p) ' repeat as necessary p = New Person(2, "Austen", "Jane", "JA") p.DisplayMethod = New Person.displayPersonDelegate _ (AddressOf DisplayPersonLastFirst) people.Add(p) p = New Person(2, "Fowles", "John", "JF") p.DisplayMethod = New Person.displayPersonDelegate _ (AddressOf DisplayPersonLastFirst) people.Add(p)

Using the DisplayMethod delegate property, Person object consumers can create custom methods to display the object's data in any format they prefer. But because the scheme defaults to the .NET standard ToString method, you haven't changed the base functionality of ToString in any other way. In fact, the only reason to override the ToString method at all is because that's what the ListBox calls by default. But you could just as easily write a Display method and have the class consumers call the Display method explicitly (in this case, by setting the ListBox DisplayMember property to "Display"), and leave ToString out of the equation altogether.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date