Windows Forms Data Mapping Custom Class Child Object Mapping

I am trying to set the DisplayMember property of my ListBox in a Windows Forms project to a property of a nested class inside a shared list that I am bound to.

Here is a simple example:

public class Security { public int SecurityId { get; set;} public SecurityInfo Info { get; set;} } public class SecurityInfo { public string Description { get; set;} } //........// public void DoIt() { List<Security> securities = new List<Security>(); //add securities to list lstSecurities.DataSource = securities; lstSecurities.DisplayMember = "Info.Description"; } 

Is this possible with a simple ListBox, or do I need to subclass a ListBox to handle this?

edit:

I try not to change these classes as they are created through the WSDL document.

+4
source share
6 answers

No, most winforms bindings do not support child properties like this.

You can do this directly using type descriptors, but this is a lot of work and not worth it.

Check generated code; it should (with any new version of tools) be a partial class ; this means that you can add additional members to the second class file, so you do not break the code generated by wsdl - i.e.

 namespace MyWsdlNamespace { partial class MyClass { public string InfoDescription { get { return Info.Description; } // and a set if you want } } } 

Now you can easily contact the "InfoDescription".

+5
source

You can add a new property that appears in Info.Description.

Something like that:

 public string InfoDescription { get { return Info.Description; } set { Info.Description = value; } } 

It will work. But I thought your example should work too.

+2
source

I know that several answers that may work for you have already been published, and this question is 3 years old, but I wanted to add another option because I ran into this problem when I was bound to data with objects in the Entity Framework.

I was attached to a ListBox, but wanted to display text from a child. All I did was handle the ListBox.Format event and change the ListControlConvertEventArgs.Value . I could get my child object because the DisplayMember that I selected for the ListBox is the parent object itself and could be accessed in the ListControlConvertEventArgs.ListItem event.

For example, a ListBox is a binding to a binding to a binding source with an objA list. objA has a property for the objB child. The DisplayMember for the ListBox (set at design time) is objB. But since the ToString() method does not return what I want for objB, I handle the Format event from the ListBox and set the e.Value (with e as ListControlConvertEventArgs ) to the object I'm looking for.

 CType(e.ListItem, objA).objB.DisplayText 
+1
source

Just override the SecurityInfo ToString method to return Description and do:

 lstSecurities.DisplayMember = "Info"; 

If you cannot change classes, the best option would be to use ViewModel. The class that takes Security and provides the properties that you want to view.

0
source

Yes, binding to nested properties can be done through BindingSource. Dan's comment on January 25 showed how this can be done for a "simple binding", i.e. Bindings to single nested properties. For "complex binding" to collections, it should be like this:

 public void DoIt() { List<Security> securities = new List<Security>(); var securitiesBindingSource = new BindingSource(); securitiesBindingSource.DataSource = securities; //add securities to list lstSecurities.DataSource = securitiesBindingSource; lstSecurities.DisplayMember = "Info.Description"; } 

Thin WARNING. Collection objects must be descendants of the same type, so information must be of the same type. Covariance of an interface will not fool it into work when the Info property depends on a type parameter, even if it is covariant, as this will make Info covariant, but a different type, for example, when Info is of type Information<out P> .

0
source

All Articles