I have a windows form with many comboboxes. They all have to display the same items and I want to be able to remove items from their list of values. So I decided to try and make a List variable so I could easily remove and insert values into it. So what I did was
List<string> Ranks = new List<string>(new string[] { "values here" });
Then in my Form1Designer.cs
this.ComboBox_Rank_0.DataSource = Ranks;
I heart ValueMember and DisplayMember were good things to have, but so far it works without them. When compiled the form loads and the comboboxes have the correct values.
The problem is that when I choose a value in one combobox the others get the same value selected, as well. Any ideas?
Use a BindingList<T>
This class allows you to handle the interaction with your list separately for each of the combos
For example
List<string> names = new List<string>()
{"Steve", "Mark", "Luke", "John", "Robert"};
BindingList<string> bl1 = new BindingList<string>(names);
ComboBox_Rank_0.DataSource = bl1;
BindingList<string> bl2 = new BindingList<string>(names);
ComboBox_Rank_1.DataSource = bl2;
The BindingList<T> requires using System.ComponentModel; and notice that you don't require the new string[] syntax in the constructor of your list
Related
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());
}
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.
I have a list
List<Control> inputBoxes = new List<Control>();
where I have added comboboxes and textboxes.
I can set the text property with inputBoxes[0].GetType().GetProperty("Text").SetValue(inputBoxes[0], "ABC", null);
but how can I add items to the comboboxes and select them?
Can I use inputBoxes[0].GetType().GetMethod() somehow?
Why do you use reflection to simply set a property?
You can use this which is much more efficient and less error-prone:
inputBoxes.OfType<TextBox>().ElementAt(0).Text = "ABC";
If you want to add items to one (or multiple) ComboBoxes:
var combos = inputBoxes.OfType<ComboBox>();
foreach(ComboBox combo in combos)
{
// add items here or set their DataDource, for example:
string[] installs = new string[]{"Typical", "Compact", "Custom"};
combo.Items.AddRange(installs);
}
Note that you need to add using System.Linq for OfType
Right now I'm maintaining 4 separate data sources and adding and removing items from each one as that item is selected/deselected in another comboBox.
AvailibleColors1 = new List<String>(new String[] { Resources.Red, Resources.Orange, Resources.Blue, Resources.White, null, });
AvailibleColors2 = new List<String>(new String[] { Resources.Red, Resources.Orange, Resources.Blue, Resources.White, null, });
AvailibleColors3 = new List<String>(new String[] { Resources.Red, Resources.Orange, Resources.Blue, Resources.White, null, });
AvailibleColors4 = new List<String>(new String[] { Resources.Red, Resources.Orange, Resources.Blue, Resources.White, null, });
This is for a simple game where players are selecting their colors and the idea is that a player should not even have the option to select a color already chosen by another player. My current method is functional but it's fragile (comboBox doesn't always update when items added/removed, not sure why) and inelegant. As always, thanks in advance!
IMHO you should use a single Observable Collection as your datasource. Bind it to all comboboxes. Now when a combobox gets selected, remove that item from OC so that other comboboxes applying it reflect that change.
ObservableCollection<T> Class
Second Option
I asked same question. And this is the link. I haven't tried it so give it a try.
This may have been already asked but I can't seem to find this specific question, so here goes...
I have a form in C# where every textbox is bound to a field in a row. Rows can be cycled through by some buttons on the bottom but all the data displayed at a time in the from is from one row. Any changes that are made get updated back to the database when the user clicks "update"
One field (class) is an enumeration (0,1,2) where only the value is stored in the database, but doesn't mean much to the user. I was asked to make this more obvious to the user, so I decided to go with a dropdown style combo box. Since the database didn't have any reference to what the values meant, I decided to use the DataBindings instead of DataSource so I could just use the index as the data bind, but it seems that SelectedItem or Value are not the way to do this.
Here is my goal:
1 exists in database, so "B" is selected in combo box.
User selects "C" and updates the database, 2 is now stored in the database.
Any thoughts on what I need to get this working?
I assume you have a BindingSource on your form to bind to the data. You can bind the SelectedIndex property of the ComboBox as follows:
comboBox.DataBindings.Add("SelectedIndex", bindingSource, "PropertyInTheDataSource");
Actually I was able to bind it to a custom Object. It's a little too much work for such a simple task. But you have complete control on Display/Value pairs. Anyway, I thought I'd share and you decide:
Create a new class (say CustomItem) with 2 fields:
Public int Value{get;set;}
public string Title {get;set;}
Then in you form:
var item1 = new CustomItem() { Title = "A", Value = 10 };
var item2 = new CustomItem() { Title = "B", Value = 20 };
var item3 = new CustomItem() { Title = "C", Value = 30 };
var lst = new List<CustomItem>();
lst.Add(item1);
lst.Add(item2);
lst.Add(item3);
comboBox1.DataSource = lst;
comboBox1.DisplayMember = "Title";
comboBox1.ValueMember = "Value";
Now You have a databound combobox in case you don't have BndingSource in your form.
Just remember to define your class's Title and Value as properties otherwise it wouldn't work.