Reputation: 2440
I should add that the objects are managed in a 3rd party .dll
so I do not actually have the object definitions in my code.
I have a List<Foo>
which I'm setting as the datasource for a ComboBox
.
Assuming Foo
object looks something like:
public class Foo
{
Settings setting;
public Foo(string title)
{
setting = new Settings();
setting.Title = title;
}
//lots of other objects and values
}
public class Settings
{
public Settings()
{
}
public String Title {get; set;}
//lot of other information
}
And my implementation here:
private void LoadList() //edited for SO testing sake, this is called in constructor
//of the form
{
var foo = new List<Foo> {
new Foo("MASTER 5DAY"),
new Foo("5 Day Reminder"),
new Foo("MASTER Welcome"),
new Foo("Welcome Letter")
};
var master = foo.Where(x => x.Settings.Title.Contains("MASTER")).ToList();
this.ddlMasterType = master; //This is the combobox
//Now here I would want the display member of the ddl to be the title of each Foo object
//But I need the value member to still contain all the other information of the Foo object
}
As listed in my implementation comments, I want to display the Foo.Settings.Title when I open the dropdown, but I still need the full object when I select it later.
Upvotes: 1
Views: 2663
Reputation: 37059
You're in a little bit of a pickle. If you set comboBox1.DataSource = foo;
, ordinarily you'd set comboBox1.DisplayMember = "SomePropertyName";
and you'd be good. But in your case you need a path, not a name, and comboBox1.DisplayMember = "settings.Title";
will be ignored.
If you could alter Foo
, you'd just add a readonly wrapper property to Foo
:
public String Title { get { return settings.Title; } }
But you can't alter Foo
.
So here's an option: Write a wrapper class that you can alter.
public class FooCarrier
{
public Foo Foo { get; set; }
public String Title { get { return Foo.settings.Title; } }
}
...
public Form1()
{
InitializeComponent();
comboBox1.DataSource = new List<Foo> {
new Foo("MASTER 5DAY"),
new Foo("5 Day Reminder"),
new Foo("MASTER Welcome"),
new Foo("Welcome Letter")
}.Select(f => new FooCarrier { Foo = f }).ToList();
comboBox1.DisplayMember = "Title";
comboBox1.ValueMember = "Foo";
comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
}
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// comboBox1.SelectedItem will be FooCarrier, but since we set
// ValueMember to "Foo", SelectedValue is the Foo property of the selected
// item.
Foo selectedFoo = (Foo)comboBox1.SelectedValue;
}
You could also omit FooCarrier
and use an anonymous type:
comboBox1.DataSource = new List<Foo> {
new Foo("MASTER 5DAY"),
new Foo("5 Day Reminder"),
new Foo("MASTER Welcome"),
new Foo("Welcome Letter")
}.Select(f => new { Foo = f, Title = f.Settings.Title }).ToList();
SelectedValue
is still Foo
, so you'll never need to cast to the actual item type.
Upvotes: 4
Reputation: 133
Try setting the displayMember to the Title Property:
master.DataSource = fooList;
master.DisplayMember = "Name"
Get the whole object by using:
Foo foo = (Foo)master.SelectedItem;
or
Foo foo = master.SelectedItem as Foo;
Upvotes: 0
Reputation: 504
You can set comboBox's data context as the whole list, and override ToString method of Foo class to show exactly what you want.
public override string ToString()
{
return /*information you want to display, for example*/setting.Title;
}
Upvotes: 0