EsoMoa
EsoMoa

Reputation: 717

WinForms Combobox: Fill with String and Object

I already have seen that there are many Topics about this,but I am not able to make them work.

I have an Combobox which shall be filled with an List of String.

  this.elementBox.DataSource = this.elementList;  
  this.elementBox.SelectedIndexChanged += new EventHandler(this.elementBox_SelectedIndexChanged);

If I put this into the Code my GUI does not appear, I suppose the assignment of the data is wrong. I already tried Bindingsource.

Then I want to fill an Combobox with an List of Objects and this does not work either. itemData is an Dictionary with an String as key and the Objectlist as value.

        box1.DataSource = itemData["ele1"];
        box1.DisplayMember = "Name";

        box2.DataSource = itemData["ele2"];
        box2.DisplayMember = "Id";

I tried to play around with DisplayMember and Value but I am not able to get it to work. The Type of the List is MyItem:

   class myItem{ int Id; Internal data;}
   class Internal {String name;}

Obviously I want to show the myItem.data.name in the Combobox, but I do not know how to get it. Furthermore what is the difference of DisplayMember and Value?

Upvotes: 0

Views: 1229

Answers (1)

Jens Meinecke
Jens Meinecke

Reputation: 2940

DisplayMember expects a public property not a private field

Change the classes:

class myItem
{ 
   public int Id {get; set}
   public Internal data {get;set;}
}

class Internal 
{
   public string Name {get; set;} 
}

Note also that the property names are case sensitive. So 'name' and 'Name' are considered to be different entities.

Further, if you are adding an object of 'myItem` class, you cannot get the combo box to access the a member of a member. You will have to do the fetching yourself:

class myItem
{ 
   public int Id {get; set}
   public Internal data {get;set;}

   public string Name { get { return data.Name; }}
}

Now by setting DisplayMember to "Name" it will reference the Name property of myItem which in turn accesses the data.Name property.

If the list comes to you from somewhere else (you don't own the list class and thus cannot modify it's code), you will have to wrap the objects inside another class and replace the list with a list of the wrapped objects:

class myItemWrapper
{
     private myItem _myItem;

     public myItemWrapper(myItem item)
     {
         _myItem = item;
     }

     public override string ToString()
     { 
         return _myItem.data.Name;
     }

     public myItem Item { get { return _myItem;}}
}

then you can get rid of the DisplayMember assignment

box1.DisplayMember = "Name";

as the ToString() will be called instead.

but you have to replace the

box1.DataSource = itemData["ele1"];

with a bit more code:

var  wrapper = new List<myItemWrapper>();

foreach(var item in itemData["ele1"]);
   wrapper.Add(new myItemWrapper(item));

box1.DataSource = wrapper;

And don't forget that, when you are handling the selected item in the listbox that you are no longer dealing with myItem objects, but myItemWrapper objects instead. So to access the actual myItem object you will have to use the Item property of the myItemWrapper class instead.

Upvotes: 3

Related Questions