How to add a custom index in ComboBox - c#

I'm looking for some help, I'm new with C# and i'm trying to make a combobox with custom indexes, I was adding the items this way
mycb.Items.Add("My value 1");
mycb.Items.Add("My value 2");
by this way I get these indexes by default 0 and 1 so I try to give the indexes that I want to the CB using Insert
mycb.Items.Insert(5,"My value 1");
mycb.Items.Insert(6,"My value 2");
this way the CB should have the indexes 5 and 6 but this is not working because when I select one of those options this error appeared
invalid argument=value of '5' is not valid for 'index'
It works when I add consecutive indexes starting by 0 but that is not what I want, how can I add the indexes that I want to the CB without having this issue? I hope you can help me, thanks.

You would make a dictionary (or array) of the items, assign it as the datasource for the combobox and set the "DisplayMember" and "ValueMember" of the combobox, like this:
Dictionary<int, string> myDictionary = new Dictionary<int, string>();
myDictionary.Add(1, "string");
myDictionary.Add(2, "string2");
myDictionary.Add(4, "string4");
mycb.DataSource = myDictionary.ToArray();
mycb.DisplayMember = "Value";
mycb.ValueMember = "Key";

Maybe adding object instead of custom index?
Referring to MSDN ComboBox.Items documentation
Although the ComboBox is typically used to display text items, you can add any object to the ComboBox. Typically, the representation of an object in the ComboBox is the string returned by that object's ToString method. If you want to have a member of the object displayed instead, choose the member that will be displayed by setting the DisplayMember property to the name of the appropriate member. You can also choose a member of the object that will represent the value returned by the object by setting the ValueMember property. For more information, see ListControl.
Code from MSDN ListControl.ValueMember documentation example
ArrayList USStates = new ArrayList();
USStates.Add(new USState("Alabama", "AL"));
USStates.Add(new USState("Washington", "WA"));
USStates.Add(new USState("West Virginia", "WV"));
USStates.Add(new USState("Wisconsin", "WI"));
USStates.Add(new USState("Wyoming", "WY"));
ListBox1.DataSource = USStates;

Related

Map enum values on ComboBox

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

Winform Combobox with DataSource as List<int>

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());
}

Assigning DisplayMember of a combo box with a value from a Tuple within a list of Tuple - C#

I have a combo box on a windows form that I am trying to populate with a list of clients. I have a List of Tuple with three values (var clients = new List<Tuple<int, string, string>>();) I am getting data from a SQL call returning a clientID, clientName, and path.
The issue I am having is, my combo box is displaying (1, companyName, c:\Path) which is the first value of my list, but what I really want to display is the companyName (Item2 in the tuple) and not the other data.
If my clients variable was just a Tuple instead of a list of Tuple I would be able to do this:
comboBoxClients.DisplayMember = clients.Item2;
comboBoxClients.ValueMember = clients.Item1
Here is the code I tried to use which didn't work:
var clients = new List<Tuple<int, string, string>>();
clients = GetClients();
comboBoxClient.DataSource = clients;
comboBoxClient.DisplayMember = clients[0].Item2;
Is there a way I can set the DisplayMember to the second item of my tuple in the list? Is there something else I should be using instead of a tuple? Any help with this is appreciated.
Try setting comboBoxClient.DisplayMember = "Item2";
DisplayMember should be a string declaring the name of the property to be diplayed. See here: http://msdn.microsoft.com/de-de/library/system.windows.forms.listcontrol.displaymember%28v=vs.110%29.aspx
Handling of ValueMember is the same.

Enum - combobox binding with one item as exception

I have a Enum which I am binding to ComboBox.
But i dont want to show one enum value in combobox items.
If I try to remove after binding it is throwing error.
cmbDisplayUnit.Items.Remove(item);
Is it possible to binding to enum and still removing or atleast hiding one of the values of Enum?
If you look at this MSDN Forum article it gives an example on how to do what you are wanting. See Sorrocco's answer.
Modified from above link:
string[] TestNames = Enum.GetNames(typeof(SampleEnumUnits));
var list = from test in TestNames where test != "Enum you wish to remove" select Enum.Parse(typeof(SampleEnumUnits), test);
cmbDisplayUnit.ItemsSource = list;
I think you need this:
cmbDisplayUnit.Items.Remove((int)item); // I assume item is enum variable
var items = Enum.GetValues(typeof(datMHD.Enums.EquipmentEnums.Request_ItemType));
var List = items.OfType<datMHD.Enums.EquipmentEnums.Request_ItemType>().ToList();
List.RemoveAll(e => e.Equals(datMHD.Enums.EquipmentEnums.Request_ItemType.Spare_Parts));
You convert the Array values to List then use RemoveAll then Assign the Item to a combo box

How to set selected value from Combobox?

I use combobox in c# windows form. I bound the item list as below:
var employmentStatus = new BindingList<KeyValuePair<string, string>>();
employmentStatus.Add(new KeyValuePair<string, string>("0", "[Select Status]"));
employmentStatus.Add(new KeyValuePair<string, string>("1", "Contract"));
employmentStatus.Add(new KeyValuePair<string, string>("2", "Part Time"));
employmentStatus.Add(new KeyValuePair<string, string>("3", "Permanent"));
employmentStatus.Add(new KeyValuePair<string, string>("4", "Probation"));
employmentStatus.Add(new KeyValuePair<string, string>("5", "Other"));
cmbEmployeeStatus.DataSource = employmentStatus;
cmbEmployeeStatus.ValueMember = "Key";
cmbEmployeeStatus.DisplayMember = "Value";
cmbEmployeeStatus.SelectedIndex = 0;
I save the selected value in database eg.1 or 2. Now I want to set selected value from database item like:
cmbEmployeeStatus.SelectedValue =employee.employmentstatus;
But combobox not selected with value. How can I do that?
Try this one.
cmbEmployeeStatus.SelectedIndex = cmbEmployeeStatus.FindString(employee.employmentstatus);
In order to do the database style ComboBoxes manually trying to setup a relationship between a number (internal) and some text (visible), I've found you have to:
Store you items in a list (You are close - except the string,string - need int,string)
DataSource property to the list (You are good)
DataMember,DataValue (You are good)
Load default value (You are good)
Put in value from database (Your question)
Get value to put back in database (Your next question)
First things first. Change your KeyValuePair to so it looks like:
(0,"Select")
(1,"Option 1")
Now, when you run your sql "Select empstatus from employees where blah" and get back an integer, you need to set the combobox without wasting a bunch of time.
Simply: *** SelectedVALUE - not Item ****
cmbEmployeeStatus.SelectedValue = 3; //or
cmbEmployeeStatus.SelectedValue = intResultFromQuery;
This will work whether you have manually loaded the combobox with code values, as you did, or if you load the comboBox from a query.
If your foreign keys are integers, (which for what I do, they all are), life is easy. After the user makes the change to the comboBox, the value you will store in the database is SelectedValue. (Cast to int as needed.)
Here is my code to set the ComboBox to the value from the database:
if (t is DBInt) //Typical for ComboBox stuff
{
cb.SelectedValue = ((DBInt)t).value;
}
And to retrieve:
((DBInt)t).value = (int) cb.SelectedValue;
DBInt is a wrapper for an Integer, but this is part of my ORM that gives me manual control over databinding, and reduces code errors.
Why did I answer this so late? I was struggling with this also, as there seems to be no good info on the web about how to do this. I figured it out, and thought I'd be nice and post it for someone else to see.
In windows Appliation
we use like this
DDLChangeImpact.SelectedIndex = DDLChangeImpact.FindStringExact(ds.Tables[0].Rows[0]["tmchgimp"].ToString());
DDLRequestType.SelectedIndex = DDLRequestType.FindStringExact(ds.Tables[0].Rows[0]["rmtype"].ToString());
Use the SelectedIndex property for the respective employee status in the combo box.
Below will work in your case.
cmbEmployeeStatus.SelectedItem =employee.employmentstatus;
When you set the SelectedItem property to an object, the ComboBox attempts to make that object the currently selected one in the list. If the object is found in the list, it is displayed in the edit portion of the ComboBox and the SelectedIndex property is set to the corresponding index. If the object does not exist in the list, the SelectedIndex property is left at its current value.
EDIT
I think setting the Selected Item as below is incorrect in your case.
cmbEmployeeStatus.SelectedItem =**employee.employmentstatus**;
Like below
var toBeSet = new KeyValuePair<string, string>("1", "Contract");
cmbEmployeeStatus.SelectedItem = toBeSet;
You should assign the correct name value pair.
cmbEmployeeStatus.Text = "text"
I suspect something is not right when you are saving to the db. Do i understand your steps as:
populate and bind
user selects and item, hit and save.. then you save in the db
now if you select another item it won't select?
got more code, especially when saving? where in your code are initializing and populating the bindinglist
A possible solution:
cmbEmployeeStatus.SelectedValue = cmbEmployeeStatus.Items.FindByText("text").Value;
try this
combobox.SelectedIndex = BindingSource.Item(9) where "9 = colum name 9 from table"
To set value in the ComboBox
cmbEmployeeStatus.Text="Something";
Try this:
KeyValuePair<string, string> pair = (KeyValuePair<string,string>)this.ComboBox.SelectedItem;

Categories