Binding of Datasource to Listbox - c#

I want to bind a OleDbDataReader to a Listbox . I have got reader with database values and i use following code for binding
List<String> cat_name = new List<string>();
while (reader.Read())
{
cat_name.Add(reader["cat_name"].ToString());
}
ProductMainCategory.DataSource = cat_name;
ProductMainCategory.DataBind();
i am getting category_id and cat_name from database. This code is setting only Listbox Text field with cat_name but i also want to fill dataValue property of Listbox. Please suggest me some good way to do this with best way .

You should be using List of some type such as KeyValuePair or Tuple or your own class to store both values. For example,
var categories = new List<KeyValuePair<string, string>>();
while (reader.Read())
{
categories.Add(new KeyValuePair<string, string>(reader["category_id "].ToString(), reader["cat_name"].ToString()));
}
ProductMainCategory.DataSource = Categories;
ProductMainCategory.DataValueField = "Key";
ProductMainCategory.DataTextField = "Value";
ProductMainCategory.DataBind();

Related

Retrieve a ListViewItem's value

I have a ListView populated with the code below. Ask you can see, I set both the DisplayMember and the ValueMember. What I am wanting to do is find a ListViewItem by its ValueMember. So essentially what I'm looking for is ListViewItem.Value. I know I can get SelectedValue for the ListView itself, but I just don't see any properties on the ListViewItem that give me what I'm looking for. Am I just missing something, or is there no way to do this?
private void PopulateList(Globals.DataFieldMappingTypes mappingType)
{
ListBox lst = GetListBox(mappingType);
ComboBox cbo = cboh.GetComboBox(new ComboBoxHandler.CboInfo(Globals.NodeTypes.DataField, mappingType));
string sql = "select DataFieldReferenceValueId, [Value] from DataFieldReferenceValueInfo where DataFieldId = " + cbo.SelectedValue.ToString();
DataTable tbl = dal.GetTable(sql, "DataFieldReferenceValue");
lst.DisplayMember = "Value";
lst.ValueMember = "DataFieldReferenceValueId";
lst.DataSource = tbl.DefaultView;
}
I think that you are not getting the values from DataTable correctly I guess.
I hope tbl.Rows[0][0].ToString() will have the DataFieldReferenceValueId and
tbl.Rows[0][1].ToString() will have the [Value]
Please check the below MSDN link
https://forums.asp.net/t/1188002.aspx?how+to+read+DataTable+Rows+value+and+put+it+into+the+string+
Instead of loading your dataTable straight in as the dataSource why don't you create a class to define the values?
public class SqlTable
{
public string Name {get;set;}
public string Value {get;set;}
}
var listPair = new List<SqlTable>();
Then load the list with your SqlDataReader and grab your desired pair with LINQ.
while (sdr.Read())
{
listPair.Add(new SqlTable() { Name = sdr[0].ToString(), Value = sdr[1].ToString() });
}
lst.DisplayMember = "Name";
lst.ValueMember = "Value";
lst.DataSoure = listPair;
SqlTable sqlTable = listPair.Find(x => x.Name == "Whatever name you are searching for") as SqlTable;
The SqlTable item is now the one you are searching for and you can get its properties by going:
string value = sqlTable.Value;
string name = sqlTable.Name;
Edit from comment begins here:
Well your first issue is that the 'lst' item in your example is a ListBox and not a ListView. It you switch it to a listview you can still feed your List of listPair items like so:
ListView lst = new ListView();
lst.View = View.Details;
foreach (var data in listPair)
{
lst.Items.Add(new ListViewItem(listPair.Name, listPair.Value);
}
So now you have a ListView that is a collection of your listPairs where each listPair is a ListViewItem. I assume you want to isolate the ListViewItem based on your value (or listPair.Value or sdr[1] or [Value] they are all the same now) in order to color it. You can now grab the listPair item like so:
SqlTable pair = listPair.Find(x => x.Value == "Whatever the Value value is that you want to color");
ListViewItem searchedItem = lst.FindItemWithText(pair.Name);
searchedItem.BackColor = System.Drawing.Color.Red; //or whatever color you choose
You can now use searchedItem to grab its index in the ListView and all its other properties. The ListPair just allows you to associate the values.

WinForms ComboBox

I'm trying to mark one of the combobox items as selected.
So I am building my combobox like this:
var drop = new Dictionary<int, string>();
while (RegReader.Read())
{
drop.Add(Convert.ToInt32(RegReader["intRulesID"]), RegReader["txtName"].ToString());
}
RegRuleDrop.DataSource = new BindingSource(drop, null);
RegRuleDrop.DisplayMember = "Value";
RegRuleDrop.ValueMember = "Key";
Now, one of the items within the RegRuleDrop should be pre selected based on a value from a reader above this code.
Now, the problem is that I need to select value based on the actual ListItem VALUE and not TEXT.
So as an example
drop.Add(1, "Test");
drop.Add(2, "Test2");
drop.Add(3, "Test3");
I need to find the index using 1,2 or 3 not Test, Test2 or Test3
Any ideas?
When you have the DataSource set to a BindingSource the only action needed to select an item given a value belonging to the ValueMember property is
drop.Add(1, "Test1");
drop.Add(2, "Test2");
drop.Add(99, "Test99");
drop.Add(3, "Test3");
.....
RegRuleDrop.SelectedValue = 99

ComboBox AutoComplete with Key/Value Pair

I have a ComboBox with the following code:
private void comboBox1_TextChanged(object sender, EventArgs e)
{
using (var service = WebServiceHelper.GetCoreService())
{
string physicianXml = service.SearchPhysicians(SessionInfo.Current.ClientCode, SessionInfo.Current.MachineName,
SessionInfo.Current.Username, comboBox1.Text);
var physicians = PhysicianItemList.FromXml(physicianXml);
AutoCompleteStringCollection autoCompleteStringCollection = new AutoCompleteStringCollection();
foreach (var physician in physicians.Items)
{
autoCompleteStringCollection.Add(physician.LastName + ", " + physician.FirstName);
}
comboBox1.AutoCompleteCustomSource = autoCompleteStringCollection;
comboBox1.Select(comboBox1.Text.Length, 0);
}
}
Basically, a user types the first few characters of a physician's name and it should populate the auto-complete list with the top 100 matching records. It works great, but I need to associate it back to a key (either the PK from the table, or the Physician's NPI number). It seems the AutoCompleteStringCollection doesn't support keys. Can anyone suggest a way of doing this? There are approximately 7 million records in the table, so I don't want to prepopulate the ComboBox.
Thanks
When you build your AutoCompleteStringCollection, build a Dictionary<String, int> for the name, id pairs as well. Then use some event (textbox validation or user submit/save click) to lookup and set the id. You could store the dictionary on the textbox Tag.
Edit
For some reason I thought you were working with a textbox control. Forget about the AutoCompleteStringCollection and just build a Dictionary<String, int>. For the combobox set your autocompletesource to ListItems, set the combobox display name and value and set the datasource to the dictionary.
combobox.DisplayMember = "key";
combobox.ValueMember = "value";
combobox.AutocompleteSource = AutocompleteSource.ListItems;
combobox.DataSource = myDictionary;
However you should only populate the datasource and autocomplete once when the user enters n characters in the combobox, otherwise it gets buggy. I tried to use this for a dynamic autocomplete once (eg the list clears if the user clear the text and retypes), but I had to forget about the combobox and use a hybrid textbox listbox approach much like this user
It looks like your problem is that AutoCompleteStringComplete was made specifically for strings (hence, the name).
You may want to look into the parents (IList, ICollection, IEnumerable) and see if you can homebrew something templated toward a key/value struct.
Too late but maybe someone will use this code :
this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
RNProveedor rnProveedor = new RNProveedor();
var listaProveedores = rnProveedor.Buscar();
Dictionary<int, String> dicTemp = new Dictionary<int, string>();
foreach (var entidad in listaProveedores)
{
dicTemp.Add(entidad.ProvNro, entidad.ProNombre);
}
this.DataSource = new BindingSource(dicTemp, null);
this.DisplayMember = "Value";
this.ValueMember = "Key";
And to select the value
public int GetValorDecimal()
{
KeyValuePair<int, string> objeto = (KeyValuePair<int, string>)this.SelectedItem;
return objeto.Key;
}
With this example you won't have any problem with duplicated strings as the examples above

Binding Dictionary To Datagridview

I wanted to bind a dictionary to a datagridview. Unfortunately Dictionary does not implement the required interface, so instead a created a List>.
Essentially I want this to be bound to a datagridview with datagridviewcomboboxcolumns. With column 1 holding the Key and column 2 holding the value.
I've tried loads of variations, but I can't seem to get this right. I've tried binding to the columns, to individual cells, and to the datagridview itself. Does anybody know how to do this?
EDIT: To clarify it's not binding to the object that's the problem. It seems to binding to the List okay, for example, if I have 4 items in the List, then 4 rows are added, however the values are blank. This is the example code:
additionalMetadata1.dataGridView1.DataSource = animal.AdditionalMetaData;
foreach (DataGridViewRow row in additionalMetadata1.dataGridView1.Rows)
{
DataGridViewCustomComboCell cell = row.Cells[0] as DataGridViewCustomComboCell;
cell.DataSource = animal.AdditionalMetaData;
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).DisplayMember = "Key";
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).ValueMember = "Key";
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).DataPropertyName = "Key";
}
Thanks.
You could use your Dictionary with the following Linq:
dataGridView.DataSource = (from d in dictionary
orderby d.Value
select new
{
d.Key,
d.Value
}).ToList();
This will create an anonymous object that will hold your Key and Value as properties. Be aware that the dictionary is by default not in a particular order.
Try like this
dataGridView1.ColumnCount = 2;
foreach (KeyValuePair<string, string> kvp in dict) {
string[] arow = new string[] { kvp.Key, kvp.Value };
dataGridView1.Rows.Add(arow);
}
or
dataGridView1.DataSource = dict.ToArray();
or
dataGridView1.DataSource = dict.Select((kv => new {
myKeys = kv.Key,
myValues = kv.Value
})).ToArray();

How to set a custom id for listitems in BulletedList control while binding?

I am binding a BulletedList control in page load to a datasource, what i want to do is to set custom IDs for this BulletedList's ListItems while binding
This custom ID will be in my current case "li_"+ItemId.ToString()
Sample Code i used to fill the bulletedList:
bulletedList.DataSource = MyDataCollection;
bulletedList.DataTextField = "Name";
bulletedList.DataValueField = "Id";
bulletedList.DataBind();
I understand now...
you mean like this?:
private void BindBulletList()
{
List<string> list = new List<string>();
list.Add("item1");
list.Add("item2");
list.Add("item3");
list.Add("item4");
list.Add("item5");
bullets.DataSource = list;
bullets.DataBind();
foreach (ListItem item in bullets.Items)
{
item.Attributes.Add("Id", "li_" + item.Text);
}
}
Does this help?
use linq:
var list = MyDataCollection.Select(x => new {Name = x.Name, Id = "li_"+ x.Id});
then bind list to bulletedlist as you have.

Categories