This may be a very simple question but I realized I could not get it work.
I have a Winform combo box with datasource as a List<int>
combo.DataSource = intList;
What do I put for .DisplayMember and .ValueMember in order to simply have a list of integer values? Not setting them will display nothing.
I have worked with other List<myObj> in which DisplayMember and ValueMember are myObj's properties. How about simple data type like int, string?
When retrieving the selected item, one could simply cast (int)(combo.SelectedItem) or have to go through the property corresponding to ValueMember?
The problem does not occur because you have a list of integers, it probably occurs because you add items to the list after assigning it to the .DataSource property. List does not have a mechanism to notify its container when items are added to or removed from it.
Either add items to the list before assigning it to the .DataSource property, or use a wrapper like BindingSource as Krishnraj Rana suggested.
Here BindingSource comes into picture. You can use it like this.
BindingSource bSource = new BindingSource();
bSource.DataSource = new List<int> { 1, 2, 3 };
combo.DataSource = bSource;
Though you can set datasource of combobox directly with list. like this -
combo.DataSource = intList;
This also works perfectly fine.
You can add items from list using foreach like this.
foreach (var v in intList)
{
comboBox1.Items.Add(v.ToString());
}
Related
I want to use a C# Windows Forms combo box to select the value of an enum:
this.comboBoxColor.DataSource = System.Enum.GetValues(typeof(System.Drawing.KnownColor));
But when I put this in the InitializeComponent, it replaces this line with a static assignment of an array with all items in the enum. It does this twice, once for the Datasource, and once for the Items property.
But these things don't work together. When having a bound DataSource, adding items to the Items list causes an error and when doin it the other way around assigning the SelectedValue property doesn't work any more.
I've tried using a separate method to do this outside the InitializeComponent method. And simply setting the DataSource as above in the separate method produces the following error:
System.InvalidOperationException: 'Can't set the SelectedValue in a ListControl with an empty ValueMember.'
Edit: Microsoft says using a simple array as a data source should be possible: https://msdn.microsoft.com/nl-nl/library/x8160f6f(v=vs.110).aspx
It's possible to specify the data source in the designer, but there it only allows selecting classes. What must a class implement to make that work?
You can write a simple method that transforms your enum to a datatable and then use the result of the method as a DataSource with a pair of well known names for the ValueMember and DisplayMember properties of the combo
public DataTable CreateTableFromEnum(Type t)
{
DataTable dt = new DataTable();
if (t.IsEnum)
{
dt.Columns.Add("key", t);
dt.Columns.Add("text", typeof(string));
foreach(var v in Enum.GetValues(t))
dt.Rows.Add(v, v.ToString());
}
return dt;
}
and call it with
var colors = CreateTableFromEnum(typeof(KnownColor));
cbo.ValueMember = "key";
cbo.DisplayMember = "text";
cbo.DataSource = colors;
Now when you look at the selected value you will get the numeric value of the color selected
Here is the thing I add manually few DataRow's to this.listBox1.Items and set in WinForms Designer the DisplayMember to column name but all I get displayed later is a list of type's name (System.Data...) .
How to solve this issue?
CODE:
list1.ForEach(x => this.listBox1.Items.Add(x)); //x is DataRow from a filled DataTable
The DisplayMember and ValueMember are applicable only when you use data binding (ListBox.DataSource). They work either with real properties, which can be retrieved by reflection, or via the .NET component model and the ICustomTypeDescriptor interface.
If you bind a DataTable directly, the GetEnumerator method and the IList implementation returns always DataRowView instances instead of DataRows. DataRowView implements the ICustomTypeDescriptor where the DisplayName can refer a column name.
So if you want to add some custom filtered list, I suggest you to create one from whatever source. For example:
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Value";
var list = Enumerable.Range(1, 10).Select(i => new {Name = i.ToString(), Value = i}).ToList();
listBox1.DataSource = list;
If Name property exists, you will see its value; otherwise, you will see the ToString of the items.
However, if you add the items programmatically (ListBox.Items), these properties are ignored and always the ToString of the items will be used.
Specify the column name you want to add to your list box:
list1.ForEach(x => this.listBox1.Items.Add(x["column_name"]));
After much searching I have still not found a solution to this.
I have created a list in VS 2010 and bound it to a ComboBox. The DataSource property shows the entire list but the combobox on the form is empty, as is the items property of the box.
private List<string> classes = new List<string>();
private BindingList<string> bindingClasses;
classes.Add("Spinning");
classes.Add("Step");
classes.Add("Pilates");
classes.Add("Kickboxing");
classes.Add("Body Sculpting");
bindingClasses = new BindingList<string>(classes);
classesComboBox.DataSource = bindingClasses;
I have also tried adding
classesComboBox.DisplayMember = "Spinning";
and without the bindingList between to no avail.
Why is this not working?
Lose the BindingList, just set the DataSource to the List<String> itself.
List<string> classes = new List<string>();
classes.Add("Spinning");
classes.Add("Step");
classes.Add("Pilates");
classes.Add("Kickboxing");
classes.Add("Body Sculpting");
classesComboBox.DataSource = classes;
classesComboBox.SelectedItem = "Spinning";
classesComboBox.DataBind();
You need to specify when it should grab the data.
Upon selecting any item from the list, I want some other property to be passed than the one already being displayed.
First of all, you have to fill your LitBox items. You have two options here:
1 - By adding items
listBox.Items.Add(new KeyValuePair<Object, String>("Key", "Text"));
2 - By binding to a data source
listBox.DataSource = objectDataSource;
listBox.DisplayMember = "Name";
listBox.ValueMember = "ID";
Now, to get the selected item you can do the following:
KeyValuePair<Object, String> listBoxItem =
(KeyValuePair<Object, String>listBox.SelectedItem;
String text = listBoxItem.Value.ToString();
Object key = listBoxItem.Key;
Refer to :
ListBox Class
KeyValuePair Structure
Set listbox DataSource to your data source
Set listbox ValueMember to the "Id"
Set listbox DisplayMember to the value you want displayed, i.e. "Name".
Actually I need to set the value member of combobox using Foreach loop
My code goes like this.
foreach(DataRow row in dsTable.Tables["mytable"].Rows)
{
combobox1.Items.Add(row["my column"]);
}
how do i set value member on it?
Here is the definition and some examples of combobox use.
msdn combobox link
Basically a combobox accepts "objects" so u could add any kind of items in it.
Hopes it helps.
You're not binding a DataSource so basically there's no point in setting the ValueMember property.
You should do this instead of the loop:
combobox1.DataSource = dsTable.Tables["mytable"];
combobox1.ValueMember = "MyValueColum";
combobox1.DisplayMember = "MyDisplayColumn";