I've read that combo boxes cannot have multiple columns. Which leaves me a bit stuck since what I want to do is display one field from a table, but return the corresponding value from a second field in the same table i.e.
I'd like to show CustomerNames in the combo box, but when the user selects a name, the CustomerID field is returned instead. Whats the best work around for this?
Best way is to use ComboBoxes DisplayMember and ValueMember properties
set the ComboBox.DisplayMember to the property you want to display. Use ValueMember for property you want to return. Then you can use the ComboBox.SelectedValue to get the current/selected ValueMember
You don't need multiple columns to implement it.
class Member
{
public string Name{get;set;}
public string Address{get;set;}
public int ID{get;set;}
public string Description
{
get
{
return string.Format("{0}, {1}", Name, Address);
}
}
}
var members = new []
{
new Member(){ID = 1, Name = "John", Address = "Addr 1"},
new Member(){ID = 2, Name = "Mary", Address = "Addr 2"}
};
m_ComboBox.DataSource = members;
m_ComboBox.DisplayMember = "Description"
m_ComboBox.ValueMember = "ID";
now you can access seleceted ID
var selectedID = m_ComboBox.CelectedValue();
The value of the ComboBoxItem does not have to be the same as the Text, consider using the ID as the value.
You can achieve the desired behaviour by setting the DisplayMember and ValueMember properties of the ComboBox to "CustomerName" and "CustomerID" respectively.
Take a look at the ValueMember property. You should set this to CustomerID. After you bind to your combobox, the actual field displayed to the user will be the CustomerName, but when you want to get the value of 'CustomerName', it will return the CustomerID.
When you want to get the value of the combobox, simply reference the SelectedValue.
If you are adamant about displaying both of these in the combobox, there are some hackish ways of doing this but I would recommend reviewing your requirements again and seeing if it is absolutely necessary.
Alternatively, you can define KeyValuePair objects with your intended Ids and text fields. Feed them to the combo, since its Items property is a collection of objects. Then, for retrieval use a cast like
var x = (KeyValuePair)combo.Items[0];
and then acces then Key and Value properties of x.
You can use Tag property of ComboBoxItem to store the value.
Related
I'm using C# Windows Forms, and I have created a listbox and I want to create a value within each individual item in this listbox that is not visible. So to do this I have choosen to use the Display Member. There is only one problem. The name of the item I create that is visible to the user, in the listBox, is not the DisplayMember in the code which is "Item Name". Instead the name of the Item I create appears as "Doc_Engine.PersonalMessageSystemForm+SomeData".
Here is my first code:
//Create an item in the listBox1.
List<SomeData> data = new List<SomeData>();
data.Add(new SomeData() { Value = 1, Text = "Hidden Text" });
listBox1.DataSource = data;
listBox1.DisplayMember = "Item Name";
And here is my second code:
//A class that contains two required strings.
public class SomeData
{
public int Value { get; set; }
public string Text { get; set; }
}
Click here to see a picture of my ListBox
I want the name of my Item in the listbox to be "Item Name". Not "Doc_Engine.PersonalMessageSystemForm+SomeData".
Update: I might use the Tag property instead. But when I do this, the same thing happens. The name of the item does not turn out as desired.
Your SomeData class doesn't have a member called Item Name. It has two members: Value and Text. So, per the docs you get the result of calling ToString instead:
If the specified property does not exist on the object or the value of DisplayMember is an empty string (""), the results of the object's ToString method are displayed instead.
Change it to Value or Text or add some other property to hold the value you want to display.
In winforms controls there is a Tag property you can set to anything you want and later retrieve. Try using that instead.
I have set of enums bound to a dropdown list.
((DropDownList)control).DataSource = DefaultSync;
((DropDownList)control).DataBind();
Here Defaultsync is the list which contains 2 enums.
List<MyEnum> DefaultSync=(List<SyncRequestTypeEnum>)(Enum.GetValues(typeof(SyncRequestTypeEnum)).Cast<SyncRequestTypeEnum>().Except(new SyncRequestTypeEnum[] { SyncRequestTypeEnum.ProjectLevel })).ToList();
Now I wanted to get the id of the enum based on the user selection of the dropdownlist.
I used the following code but it is giving an error as the list does not contain value for it.
public int EnumID
{
get
{
return Convert.ToInt32(ddlselection.Selectedvalue);
}
set
{
ddlselection.SelectedValue = Convert.ToString(value);
}
}
Can someone help on this?
Error is :
'ddlselection has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
In order to use SelectedValue property you need to specify which property of your data item is the value property and which one is the displayed text. I would suggest changing your code to something like this:
var list = control as DropDownList;
list.DataSource = Enum.GetValues(typeof(SyncRequestTypeEnum))
.Cast<SyncRequestTypeEnum>()
.Except(/*..*/)
.Select(x => new KeyValuePair<SyncRequestTypeEnum, string>(x, x.ToString())
.ToList();
list.DataValueField = "Key";
list.DataTextField = "Value";
list.DataBind();
And your property should work fine.
Another example and more detailed explanation on MSDN.
I have a CheckedListBox that I populate with a List of custom "DBitemtype" objects which I do through first setting the DataSource, then the DisplayMember, and ValueMember properties of the CheckedListBox "clbItemType". Now at runtime, the user has options to change the items so I have an event that rebinds the CheckedListBox with a different list of the same "DBitemtype" objects by first setting the DataSource to null, and then setting the DataSource to the new list, then setting the DisplayMember and ValueMember properties again to the exact same values like so:
clbItemType.DataSource = null;
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
clbItemType.Refresh();
Both string constants used for DisplayMember and ValueMember describe public string properties in the DBitemtype class.
The issue I'm having is that sometimes the DisplayMember gets set with "ItemName" and sometimes it doesn't and just stays as "" when I step through the code. I can't seem to find a pattern as to why it happens only sometimes. No error or exception is thrown.
Al I could find was "If the new value of the DisplayMember cannot be set, the previous value is maintained." from the msdn article here CheckedListBox.DisplayMember Property
So I guess this is a 2-part question:
1) Has anyone else had this problem?
2) What are the conditions that will cause the DisplayMember to not be set?
I'm not sure if this helps, but I did find out that DisplayName does not like public fields (public int x;), only public properties (public int x { get; set; };).
So, I would try to make sure that ItemName or any other potential DisplayName values are in fact public properties of DBitemtype.
It might look the same, but:
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
is not the same as:
clbItemType.DisplayMember = DBitemtype.Columns.ItemName; // String constant - value "ItemName"
clbItemType.ValueMember = DBitemtype.Columns.ID; // String constant - value "ID"
clbItemType.DataSource = _SelectedItemTypes; // A List<DBitemtype>
Set your members first, then change your DataSource. Changing a DataSource will fire event triggers and then return to the code block.
I have table with 4 primary key fields. I load that in to drop down list in my WinForm application created by using C#.
On the TextChanged event of drop down list I have certain TextBox and I want to fill the information recived by the table for the certain field I selected by the drop down list.
So as I say the table having 4 fields. Can I get those all 4 fields into value member from the data set, or could you please tell me whether is that not possible?
Thank you.
Datatable dt=dba.getName();
cmb_name.ValueMember="id";
cmb_name.DisplayMember="name";
cmb_name.DataSource=dt;
this is normal format.. but i have more key fields.. so i need to add more key fields..
You can use DataSource property to bind your source data to the ComboBox (e.g. a List of Entities, or a DataTable, etc), and then set the DisplayMember property of the ComboBox to the (string) name of the field you want to display.
After the user has selected an Item, you can then cast the SelectedItem back to the original row data type (Entity, DataRow, etc - it will still be the same type as you put in), and then you can retrieve your 4 composite keys to the original item.
This way you avoid the SelectedValue problem entirely.
Edit:
Populate as follows:
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
// Ignore ValueMember and Selected Value entirely
When you want to retrieve the selected item
var selectedRow = (cmb_name.SelectedItem as DataRowView );
Now you can retrieve the 4 values of your PK, e.g. selectedRow["field1"], selectedRow["field2"], selectedRow["field3"] etc
If however you mean that you want to DISPLAY 4 columns to the user (i.e. nothing to do with your Table Key), then see here How do I bind a ComboBox so the displaymember is concat of 2 fields of source datatable?
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
DataRowView selectedRow = (cmb_name.SelectedItem as DataRowView );
The result will be here:
MessageBox.Show(selectedRow.Row[0].ToString());
MessageBox.Show(selectedRow.Row[1].ToString());
MessageBox.Show(selectedRow.Row[2].ToString());
MessageBox.Show(selectedRow.Row[3].ToString());
.....
If you want to get some data from a ComboBox in to a List you can use something like this
List<string> ListOfComboData = new List<string>();
ListOfComboData = yourComboBox.Items.OfType<string>().ToList<string>();
I have no real idea if this is what you mean as the question is very poorly structured. I hope this helps...
Edit: To put the selected text in to some TextBox use
yourTextBox.Text = youComboBox.Text;
in the SelectedIndexChanged event of your ComboBox.
You could follow the approach here with the following class:
public class ComboBoxItem
{
public string Text { get; set; }
public object[] PrimaryKey { get; set; }
}
private void Test()
{
ComboboxItem item = new ComboboxItem();
item.Text = "Item text1";
item.PrimaryKey = new object[] { primaryKey1, primaryKey2, primaryKey3, primaryKey4};
comboBox1.Items.Add(item);
comboBox1.SelectedIndex = 0;
MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}
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.