I am using C# with a Windows Application Form. In this I have a combobox. What is the code to add the dropdown selections? From my googling so far I presume I need to setup an arraylist for the details?
To add Items to the ComboBox you have two options:
Either add them to the Items collection:
comboBox1.Items.Add("abc");
comboBox1.Items.Add("def");
Or use data binding:
comboBox1.DataSource = myList;
or with an array:
comboBox1.DataSource = myArray;
For the first variant you can only use strings as items, while with data binding you can bind a collection of more complex objects. You can then specify what properties are displayed:
comboBox1.DisplayMember = "Name";
and what are treated as value:
comboBox1.ValueMember = "ID";
You can access the original object that is selected later with
comboBox1.SelectedItem
or the value with
comboBox1.SelectedValue
The value is the property you specified with ValueMember.
You can use ComboBox1.Items.Add("Item") to add items 1 at a time, or ComboBox1.Items.AddRange(MyArray) to add a whole list of items at once. Each item that you add can be a string, in which case it is displayed directly in the dropdown list, or it can be an object, in which case the DisplayMember property of the combo box is used to determine which of the objects properties will appear in teh dropdown list.
Related
I am creating a ComboBox array dynamically and the DataSource for all the ComboBox is a single integer list that contains some integers. But when I change a value say X in any one combo box then all other combo values get reset to value X.
So here is the situation:
All combo box controls are bound to a single list
When I change selected item of a combo box, selected item of all other combo box controls also change.
How can I stop these behavior?
Since you are binding all combo boxes to the same data source - a single list - they are using a single BindingManagerBase.
So when you choose an item from one of combo boxes, the current Position of the shared binding manager base changes and all combo boxes goes to that position of their shared data source.
To solve the problem you can bind them to different data source:
You can bind them to yourList.ToList() or any other list for example different BindingList<T>.
combo1.DataSource = yourList.ToList();
combo2.DataSource = yourList.ToList();
You can use different BindingSource for them and set your list as DataSource of BindingSource
combo1.DataSource = new BindingSource { DataSource= yourList};
combo2.DataSource = new BindingSource { DataSource= yourList};
Also as another option:
You can use different BindingContext for your combo boxes. This way even when you bind them to a single list, they are not sync anymore.
combo1.BindingContext = new BindingContext();
combo1.DataSource = yourList;
combo2.BindingContext = new BindingContext();
combo2.DataSource = yourList;
In fact all controls of the form use a shared BindingContext. When you bind 2 controls to a same data source, then they also use the same BindingManagerBase this way, when you for example move to next record, all controls move to next record an show value from bound property of next record. This is the same behavior that you are seeing from your combo boxes. Being sync for controls which are using the same BindingManagerBase is a desired behavior. Anyway sometimes we don't need such behavior. The post shares the reason and the solution.
I'm trying to sort the items in a ListBox. However, upon doing so the Item Value gets set to the Item Text. Any help would be appreciated.
lbxCustomers.DataSource = lbxCustomers.Items.Cast<ListItem>().Reverse().ToList();
lbxCustomers.DataBind();
May be first you should store the list in generic collection and then sort it. Something like this:
List<ListItem> list = new List<ListItem>(lbxCustomers.Items.Cast<ListItem>());
list = list.OrderBy(li => li.Text).ToList<ListItem>();
lbxCustomers.Items.Clear();
lbxCustomers.Items.AddRange(list.ToArray<ListItem>());
Try resetting the DisplayMember and ValueMember properties of the Listbox after setting the DataSource. A lot of times if a control is already bound and you set the DataSource again, then it drops the DisplayMember/ValueMember properties.
Try sorting the list separately.
Point the Text value and Data value in the next step.
Databind the control.
I have a ComboBox (Windows Forms) that is bound to a List. It is created at design time. When the List contents are changed my code calls a function to refresh the data binding. This works fine for .NET 3.5:
BindingData.SuspendBinding();
DataSource = null;
DataSource = BindingData;
BindingData.ResumeBinding();
I have switched to .NET 4.0 and it has stopped working. Specifically after stepping through this code the VS debugger shows BindingData.DataSource refers to a list with 127 items, but the ComboBox Items property contains zero items.
See this SO question along a similar theme: ComboBox Items Count Doesn't Match DataSource.
I have tried everything I can think of. Currently my code looks like the following and still doesn't work:
BindingData.SuspendBinding();
DataSource = null;
DataSource = BindingData;
BindingData.ResumeBinding();
BindingContext Dummy = this.BindingContext;
Invalidate();
PerformLayout();
I tried switching from List to BindingList and that didn't help. I had to switch from .NET 3.5 to .NET 4.0 against my will so this is pretty frustrating. I'm sure there is a specific sequence that works. Any ideas?
This is how I am attaching the data source to the ComboBox:
private BindingSource BindingData = new BindingSource();
BindingData.DataSource = Nodes;
DataSource = BindingData;
thanks, Andy
I solved it. I guess at some point I made what I thought was a minor change but actually wasn't. This code was moved from being called when the ComboBox is being displayed to when it was being created. It didn't yet have a handle and so the data binding cannot be refreshed.
I added another refresh of the databinding again in a ComboBox.HandleCreated event and it works.
thanks, Andy
Why you're suspending and resuming the BindingSource? If you just change your DataSource there will be no performance pitfalls.
According to How to: Bind a Windows Forms ComboBox or ListBox Control to Data you can use the ComboBox's DisplayMember property:
//Sample for C++ .NET:
List<String^>^ options = gcnew List<String^>();
options->Add("Option 1");
options->Add("Option 2");
comboBox.DataSource = options;
comboBox.DisplayMember = "Length";//this causes an DataSource update but the ComboBox would
//show an item's length instead of the item itself
comboBox.DisplayMember = ""; //reset -> the ComboBox calls each List item's ToString
//member
"Length" refers to a public property of the String class. Better would be a property that refers directly to the string's characters. The only remaining public property of String is Chars but I couldn't make it work. So we reset DisplayMember by comboBox.DisplayMember = "", causing the ComboBox to call each List item's (a String) ToString method => problem solved.
Other List entries than Strings can be handled by the ComboBox's properties DisplayMember and ValueMember (they also apply to other controls):
DisplayMember & ValueMember
I have a Gridview in which i have two templatefields of dropdownlist. I bound them on runtime with same list item.
li = new listitem ("1","1");
dl1.items.add(li);
dl2.items.add(li);
li = new listitem ("2","2");
dl1.items.add(li);
dl2.items.add(li);
li = new listitem ("3","3");
dl1.items.add(li);
dl2.items.add(li);
dl1.selectedvalue = "2";
dl2.selectedvalue = "3";
After executing above, dl1 & dl2 both show me "3" as selected value. Why?
I know the work around of using 2 different listitems while binding but i wanna know why the above happens?
Looking at just the last part of the code: you've got a single list item, and it's appearing in two different lists. But it's still one object. How would you expect one object to have two different values for a single property (SelectedValue)?
The ListItem class has a property "Selected" which marks if the item is selected. I haven't checked the DDL SelectedValue property to see what it does, but my guess is that the ListItem.Selected property is being set to true, and since you are using the same object in both drop-down lists, it is being marked as 'selected' in both.
I'm sure if this was a multi-select list, both "2" and "3" would be marked as 'selected'.
You have to instantiate each list item for each drop down list.
ListItem li1 = new ListItem("1","1");
dl1.items.add(li1);
ListItem li2 = new ListItem("1", "1");
dl2.items.add(li2);
Edit:
Jon described what I want to mean. You have only one object that has a value. So don't expect different values for each drop down list.
When you set dl1 to "3" then both of them will get the same value because both drop down lists reference to same object!
the listitem is being shared among the two drop downs. when you set the selected value for one of the drop downs it sets the list item as being selected. since the listitem is being shared it's selected in both drop downs
I would think it would be a ref vs value problem. I am sure both d1 and d2 would be pointing to the same spot in memory if the are added from the same list item...
I currently have a class and I'm trying to create an easy GUI to create a collection of this class. Most of the attributes of this class are strings. However, one of the attributes I want the user to be able to set is an Enum. Therefore, I would like the user interface, to have a dropdownlist for this enum, to restrict the user from entering a value that is not valid. Currently, I am taking the initial list of objects, adding them to a DataTable and setting the DataSource of my DataGridView to the table. Works nicely, even creates a checkbox column for the one Boolean property. But, I don't know how to make the column for the enum into a dropdownlist. I am using C# and .NET 2.0.
Also, I have tried assigning the DataSource of the DataGridView to the list of my objects, but when I do this, it doesn't help with the enum and I'm unable to create new rows in the DataGridView, but I am definitely not bound to using a DataTable as my DataSource, it was simply the option I have semi-working.
I do not know if that would work with a DataGridView column but it works with ComboBoxes:
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
and:
MyEnum value = (MyEnum)comboBox1.SelectedValue;
UPDATE: It works with DataGridView columns too, just remember to set the value type.
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.Name = "My Enum Column";
col.DataSource = Enum.GetValues(typeof(MyEnum));
col.ValueType = typeof(MyEnum);
dataGridView1.Columns.Add(col);
Or, if you need to do some filtering of the enumerator values, you can loop through Enum.GetValues(typeof(EnumeratorName)) and add the ones you want using:
dataGridViewComboBoxColumn.Items.Add(EnumeratorValue)
As an aside, rather than using a DataTable, you can set the DataSource of the DataGridView to a BindingSource object, with the DataSource of the BindingSource object set to a BindingList<Your Class>, which you populate by passing an IList into the constructor.
Actually, I'd be interested to know from anyone if this is preferable to using a DataTable in situations where you don't already have one (i.e. it is returned from a database call).