I have a combobox cmbCourses and I am populating my this code
var _courses = new DatabaseHandler().GetAllCourses();
foreach (var a in _courses)
{
ComboBoxItem item = new ComboBoxItem();
item.Text = a.Value;
item.Value = a.Key;
cmbCourses.Items.Add(a.Value);
}
public Dictionary<int, String> GetAllCourses()
{
Dictionary<int, String> courses = new Dictionary<int, String>();
var connection = DatabaseConnector.Instance();
if(connection.IsConnect())
{
connection.Connection.Open();
string query = "SELECT * FROM courses";
cmd = new MySqlCommand(query, connection.Connection);
cmd.Prepare();
var result = cmd.ExecuteReader();
while(result.Read())
{
courses.Add(result.GetInt16(0), result.GetString(1));
}
}
connection.Connection.Close();
return courses;
}
But when I try to get key it shows value instead
using this code
MessageBox.Show(cmbCourses.SelectedItem.ToString());
You are only adding the value to the ComboBox. Add the KeyValuePair to the ComboBox and set the DisplayMemberPath and SelectedValuePath properties:
var _courses = new DatabaseHandler().GetAllCourses();
foreach (var a in _courses)
{
cmbCourses.Items.Add(a);
}
cmbCourses.DisplayMemberPath = "Value";
cmbCourses.SelectedValuePath = "Key";
You can then get the key of the selected item like this:
var item = cmbCourses.SelectedItem as KeyValuePair<int, String>;
if (item != null)
MessageBox.Show(item.Key);
You can use the GetValue() method to get the value rather than the display text:
MessageBox.Show(cmbCourses.GetValue().ToString());
Seems you have problem in adding items to your combobox, you are adding only the value by this line cmbCourses.Items.Add(a.Value);, Can you try this :
cmbCourses.Items.Add(item);
Then you can use this line to get the value :
MessageBox.Show(cmbCourses.SelectedValue.ToString());
Don't forget to set these for your combobox :
cmbCourses.DisplayMember = "YOUR DISPLAY FIELD NAME";
cmbCourses.ValueMember = "YOUR VALUE FIELD NAME";
Related
I need to create a combobox autocomplete which display text Name but when I click on text it gets value "ID" binding with "Name". I have already created a code but it is not working and I'm so confusing with set display text and value into combobox and autocomplete data-source binding.
private void loadAutoCompleteValues()
{
autoCompleteCombo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
autoCompleteCombo.AutoCompleteSource = AutoCompleteSource.CustomSource;
DataTable products;
con.MysqlQuery("select * from products");
products = con.QueryEx();
Dictionary<string, string> comboSource = new Dictionary<string, string>();
for (int i = 0; i < products.Rows.Count; i++)
{
DataRow dr = products.Rows[i];
comboSource.Add(dr["id"].ToString(), dr["name"].ToString());
}
autoCompleteCombo.DataSource = new BindingSource(comboSource, null);
autoCompleteCombo.DisplayMember = "Value";
autoCompleteCombo.ValueMember = "Key";
}
private void autoCompleteCombo_SelectedIndexChanged(object sender, EventArgs e)
{
string key = ((KeyValuePair<string, string>)autoCompleteCombo.SelectedItem).Key;
string value = ((KeyValuePair<string, string>)autoCompleteCombo.SelectedItem).Value;
MessageBox.Show(key + " " + value);
}
I may be incorrect here, however using your code I simply added the line autoCompleateCombo.AutoCompleteSource = AutoCompleteSource.ListItems; to your code and it worked as expected.
autoCompleateCombo.DataSource = new BindingSource(comboSource, null);
autoCompleateCombo.DisplayMember = "Value";
autoCompleateCombo.ValueMember = "Key";
autoCompleateCombo.AutoCompleteSource = AutoCompleteSource.ListItems; //<-- Added this line
I currently have a dictionary which contains a key value and a list associated with that key.
I have read How to bind Dictionary to ListBox in winforms and when I try to implement that it just displays the key value.
What I am trying to do is have two separate listboxs. In box 1 you select the key value, when this happens box 2 displays the list. The current code is below:
var xmlDoc2 = new XmlDocument();
xmlDoc2.Load(textBox1.Text);
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
var node = xmlDoc2.SelectNodes("pdml/packet/proto[#name='ip']/#showname");
foreach (XmlAttribute attribute1 in node)
{
string ip = attribute1.Value;
var arr = ip.Split(); var src = arr[5]; var dst = arr[8];
List<string> l;
if (!dict.TryGetValue(src, out l))
{
dict[src] = l = new List<string>();
}
l.Add(dst);
listBoxSRC.DataSource = new BindingSource(dict, null);
listBoxSRC.DisplayMember = "Value";
listBoxSRC.ValueMember = "Key";
}
What this does so far is displays the key value in listBoxSRC, which is fine. What I need to do is display the list in listBoxDST.
I also looked at using ListView to rectify this issue but I couldn't figure out how it worked.
I know there should be a listBoxSRC_SelectedIndexChange somewhere but I keep getting 'dict doesn't appear in this context' errors.
Thanks
I jotted up something real quick with a pair of list boxes. Just make any form with a pair listboxes in it and wire up the event to try it yourself. By using the SelectedItem and casting it as the KeyValuePair that it is, you don't have to declare that dictionary outside of the method scope, as shown below.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.DataSource = new BindingSource(new Dictionary<string, List<string>>
{
{"Four-Legged Mammals", new List<string>{"Cats", "Dogs", "Pigs"}},
{"Two-Legged Mammals", new List<string>{"Humans", "Chimps", "Apes"}}
}, null);
listBox1.DisplayMember = "Value";
listBox1.ValueMember = "Key";
}
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
if (listBox1.SelectedItem != null)
{
var keyValue = (KeyValuePair<string, List<String>>) listBox1.SelectedItem;
listBox2.DataSource = keyValue.Value;
}
else
{
listBox2.DataSource = null;
}
}
I want to add some items to a combobox like this :
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
ComboboxItem item = new ComboboxItem();
item.Text = "choose a server...";
item.Value = "-1";
ComboBox_Servers.Items.Add(item);
...
and read those texts and values in SelectedIndexChanged like this :
private void ComboBox_Servers_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show(ComboBox_Servers.SelectedValue.ToString());
}
But SelectedValue is always null! what is the problem and how can I fix it?
You can take the SelectedItem and cast it back to your class and access its properties.
MessageBox.Show(((ComboboxItem)ComboBox_Countries_In_Silvers.SelectedItem).Value);
Edit You can try using DataTextField and DataValueField, I used it with DataSource.
ComboBox_Servers.DataTextField = "Text";
ComboBox_Servers.DataValueField = "Value";
try this:
ComboBox cbx = new ComboBox();
cbx.DisplayMember = "Text";
cbx.ValueMember = "Value";
EDIT (a little explanation, sory, I also didn't notice your combobox wasn't bound, I blame the lack of caffeine):
The difference between SelectedValue and SelectedItem are explained pretty well here: ComboBox SelectedItem vs SelectedValue
So, if your combobox is not bound to datasource, DisplayMember and ValueMember doesn't do anything, and SelectedValue will always be null, SelectedValueChanged won't be called. So either bind your combobox:
comboBox1.DisplayMember = "Text";
comboBox1.ValueMember = "Value";
List<ComboboxItem> list = new List<ComboboxItem>();
ComboboxItem item = new ComboboxItem();
item.Text = "choose a server...";
item.Value = "-1";
list.Add(item);
item = new ComboboxItem();
item.Text = "S1";
item.Value = "1";
list.Add(item);
item = new ComboboxItem();
item.Text = "S2";
item.Value = "2";
list.Add(item);
cbx.DataSource = list; // bind combobox to a datasource
or use SelectedItem property:
if (cbx.SelectedItem != null)
Console.WriteLine("ITEM: "+comboBox1.SelectedItem.ToString());
Dictionary<int,string> comboSource = new Dictionary<int,string>();
comboSource.Add(1, "Sunday");
comboSource.Add(2, "Monday");
Aftr adding values to Dictionary, use this as combobox datasource:
comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
This is similar to some of the other answers, but is compact and avoids the conversion to dictionary if you already have a list.
Given a ComboBox "combobox" on a windows form and a class SomeClass with the string type property Name,
List<SomeClass> list = new List<SomeClass>();
combobox.DisplayMember = "Name";
combobox.DataSource = list;
Which means that combobox.SelectedItem is a SomeClass object from list, and each item in combobox will be displayed using its property Name.
You can read the selected item using
SomeClass someClass = (SomeClass)combobox.SelectedItem;
combo1.DisplayMember = "Text";
combo1.ValueMember = "Value";
combo1.Items.Add(new { Text = "someText"), Value = "someValue") });
dynamic item = combo1.Items[combo1.SelectedIndex];
var itemValue = item.Value;
var itemText = item.Text;
Unfortunatly "combo1.SelectedValue" does not work, i did not want to bind my combobox with any source, so i came up with this solution. Maybe it will help someone.
I create one datalayer method
public static List<SegmentBL> GetAllSegment(string SortDirection, string SortExpression)
{
var ds = DBHelper.GetDatabase().ExecuteDataSet("UDS_Select_SegmentMaster");
var val = ds.Tables[0].AsEnumerable().Select(r => new SegmentBL
{
_SegmentId = Convert.ToInt32(r[0].ToString()),
_SegmentName = r[1].ToString()
});
List<SegmentBL> list = val.ToList();
return list;
}
from that I create one Bussiness logic method
public DropDownList GetAll(string SortDirection, string SortExpression)
{
var list = new DropDownList();
list.DataSource = SegmentDL.GetAllSegment(SortDirection, SortExpression);
list.DataTextField = "_SegmentName";
list.DataValueField = "_SegmentID";
list.DataBind();
ListItem item = new ListItem();
item.Text = "--Select--";
item.Value = "0";
list.Items.Insert(0, item);
return list;
}
Finally Presentation Layer Method for filling dropdownlist
private void FillSegment()
{
ddlSegment.DataSource = seg.GetAll(General.SortAscending,"SegmentID").Items;
ddlSegment.DataBind();
ddlSegment.DataTextField = "_SegmentName";
ddlSegment.DataValueField = "_SegmentID";
}
It's working fine except the DataTextField and DataValueField not assign properly. Currently DataTextField and DataValueField same. What is mistake I did in above code.
You are binding before the elements are added to the datasource bind after the elements being added. You may pass dropdownlist to your method intead of creating local drop down in GetAll method.
public DropDownList GetAll(string SortDirection, string SortExpression, DropDownList list)
{
// var list = new DropDownList(); //Remove this line
list.DataSource = SegmentDL.GetAllSegment(SortDirection, SortExpression);
list.DataTextField = "_SegmentName";
list.DataValueField = "_SegmentID";
ListItem item = new ListItem();
item.Text = "--Select--";
item.Value = "0";
list.Items.Insert(0, item);
list.DataBind();
return list;
}
Move the Databind() line.
private void FillSegment()
{
ddlSegment.DataSource = seg.GetAll(General.SortAscending,"SegmentID").Items;
ddlSegment.DataTextField = "_SegmentName";
ddlSegment.DataValueField = "_SegmentID";
ddlSegment.DataBind(); //After and not before defining the fields value
}
I am working on exporting data and right now some fields export the value, instead of the text. So I am saving the object that returns the text and value to a list box and matching it to the value in the listbox from the object like so:
MaterialDB materials = new MaterialDB();
DropDownList listBoxMaterials = new DropDownList();
listBoxMaterials.DataSource = materials.GetItems(ModuleId, TabId);
listBoxMaterials.DataBind();
string materialString = "";
foreach (ListItem i in listBoxMaterials.Items)
{
if (i.Value == row["MaterialTypeID"].ToString())
{
materialString = i.Text;
}
}
When I use this for the i.Value it always returns "System.Data.DataRowView" instead of the actual value. I'm doing this all in code behind. Anyway around this to get it to work?
Thanks!
You need to set the DataTextField and DataValueField properties of the DropDownList. Example:
MaterialDB materials = new MaterialDB();
DropDownList listBoxMaterials = new DropDownList();
listBoxMaterials.DataSource = materials.GetItems(ModuleId, TabId);
listBoxMaterials.DataTextField = "MaterialName";
listBoxMaterials.DataTextValue = "MaterialID";
listBoxMaterials.DataBind();
string materialString = "";
foreach (ListItem i in listBoxMaterials.Items)
{
if (i.Value == row["MaterialTypeID"].ToString())
{
materialString = i.Text;
}
}