I'm using a CheckedListBox (System.Windows.Forms.CheckListBox) and running through some code to populate items in the list using a DataSet. My problem is that I can't seem to figure out how to set the Selected Value property, or find the right property to set!
Here's my code that successfully adds in the items:
for (int i = 0; i < projectsDataSet.tblResources.Rows.Count; i++)
{
clbResources.Items.Add(projectsDataSet.tblResources.Rows[i]["Description"].ToString());
}
There are no useful overloads on the .Add method that takes a value parameter and I can't seem to get to a value property of an item.
I guess the bottom line of what I need is the items in the CheckedListBox to display items using one field from my DataSet (like a description) and use another to store that item's value (like a primary key), so would appreciate suggestions to achieve that, thanks!
First make a class for your list box items...
public class Thing
{
public string Key { get; set; }
public string Value { get; set; }
public override string ToString()
{
return Key + "--" + Value;
}
}
Then add items to your CheckListBox like so:
for (int i = 0; i < projectsDataSet.tblResources.Rows.Count; i++)
{
clbResources.Items.Add(new Thing()
{
Key = projectsDataSet.tblResources.Rows[i]["Key"].ToString(),
Value = projectsDataSet.tblResources.Rows[i]["Description"].ToString()
}, isChecked);
}
I had had the same issue. Luckily you there is workaround to this.
if the number of items and order of items in ListBox & DataTable is same then you can get the corresponding value as below
ListBox.SelectedIndexCollection items = checkedListBox1.SelectedIndices;
for(int i=0;i<items.Count;i++)
string selectedValue = projectsDataSet.tblResources.Rows[items[i]]["ValueColumn"].ToString();
Related
I have one combobox in which I have set DataSource Value, but when I try to set SelectedValue, the ComboBox returns null. so please help.
BindingList<KeyValuePair<string, int>> m_items =
new BindingList<KeyValuePair<string, int>>();
for (int i = 2; i <= 12; i++)
m_items.Add(new KeyValuePair<string, int>(i.ToString(), i));
ComboBox cboGridSize = new ComboBox();
cboGridSize.DisplayMember = "Key";
cboGridSize.ValueMember = "Value";
cboGridSize.DataSource = m_items;
cboGridSize.SelectedValue = 4;
when I set SelectedValue with 4 then it returns NULL.
Agree with #Laazo change to string.
cboGridSize.SelectedValue = "4";
or somthing similar to this
int selectedIndex = comboBox1.SelectedIndex;
Object selectedItem = comboBox1.SelectedItem;
MessageBox.Show("Selected Item Text: " + selectedItem.ToString() + "\n" +
"Index: " + selectedIndex.ToString());
and refer to this looks as if it would be good for your issue:
https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.selecteditem(v=vs.110).aspx
How do I set the selected item in a comboBox to match my string using C#?
Getting selected value of a combobox
I came across this question while also trying to solve this problem. I solved it by creating the following extension method.
public static void ChooseItem<T>(this ComboBox cb, int id) where T : IDatabaseTableClass
{
// In order for this to work, the item you are searching for must implement IDatabaseTableClass so that this method knows for sure
// that there will be an ID for the comparison.
/* Enumerating over the combo box items is the only way to set the selected item.
* We loop over the items until we find the item that matches. If we find a match,
* we use the matched item's index to select the same item from the combo box.*/
foreach (T item in cb.Items)
{
if (item.ID == id)
{
cb.SelectedIndex = cb.Items.IndexOf(item);
}
}
}
I also created an interface called IDatabaseTableClass (probably not the best name). This interface has one property, int ID { get; set; } To ensure that we actually have an ID to compare to the int id from the parameter.
I have a Dictionary<string, ValuePair> that contains information about a previous state of my checkedlistbox control. I want to try to iterate through that Dictionary and adjust my current checkedlistbox to reflect that. The info contained in a Dictionary is a Name as string which matches an item in a list box so I can use that to call FindStringExact() and then the ValuePair class contains a bool value for whether that item was checked and an integer that is an index value for where that item was in a list previously.
How can I re-set my checkedlistbox from that info? I need to mention that my list box is bound to inputData.Cameras list of custom class objects via DataSource property. Here's my attempt at setting the check state which works, but I can't wrap my head around how to set the order since to do that I need to edit the source list that the control is bound to:
foreach (KeyValuePair<string, ValuePair> item in presets.JumpCameras)
{
int index1 = lbCameras.FindStringExact(item.Key);
if (index1 != -1)
{
UnifyCamera camera = lbCameras.Items[index1] as UnifyCamera;
lbCameras.SetItemCheckState(index1, item.Value.Value1 == true ? CheckState.Checked : CheckState.Unchecked);
}
}
my ValuePair class:
public struct ValuePair
{
public bool Value1;
public int Value2;
public ValuePair(bool x, int y)
{
Value1 = x;
Value2 = y;
}
}
One can access the inputData.Cameras and that will return a List<UnifyCamera> where UnifyCamera.Name will match/or not if it doesn't exist in the current control a Key value from the Dictionary.
So I went at it a little brute force method and split the task into two sequences of things. First I re-created a source list order and re-bound my list box to it to refresh. Then I set all of the check states for the items in a list. Curious if there is a more efficient way to do this:
// modify source list order
for (int i = 0; i < lbCameras.Items.Count; i++)
{
UnifyCamera cam = lbCameras.Items[i] as UnifyCamera;
if (presets.JumpCameras.ContainsKey(cam.Name))
{
this.inputData.Cameras.Remove(cam);
this.inputData.Cameras.Insert(presets.JumpCameras[cam.Name].Index, cam);
}
}
// re-set the list box bounding to re-set the order.
((ListBox)lbCameras).DataSource = null;
((ListBox)lbCameras).DataSource = this.inputData.Cameras;
((ListBox)lbCameras).DisplayMember = "Name";
// set check boxes
foreach (KeyValuePair<string, ValuePair> item in presets.JumpCameras)
{
int index1 = lbCameras.FindStringExact(item.Key);
if (index1 != -1)
{
lbCameras.SetItemCheckState(index1, item.Value.Checked == true ? CheckState.Checked : CheckState.Unchecked);
}
}
How can I call my function in this data gridview? I would like to make the sum of these two to be displayed in the highlighted datagridview:
foreach (DataRow row in dt.Rows) {
datagridview_information.Rows.Add();
datagridview_information.Rows[counterSelected].Cells[0].Value = row["BrandName"].ToString();
datagridview_information.Rows[counterSelected].Cells[1].Value = row["GenericName"].ToString();
datagridview_information.Rows[counterSelected].Cells[2].Value = row["PresDayOfIntake"].ToString();
datagridview_information.Rows[counterSelected].Cells[3].Value = row["Status"].ToString();
datagridview_information.Rows[counterSelected].Cells[4].Value = "5";
datagridview_information.Rows[counterSelected].Cells[5].Value = medicineLeft();
datagridview_information.Rows[counterSelected].Cells[7].Value = row["ContainerNumber"].ToString();
datagridview_information.Rows[counterSelected].Cells[8].Value = row["Status"].ToString(); ;
counterSelected++;
}
}
}
public int medicineLeft()
{
for (int i = 0; i < datagridview_schedule.Rows.Count; ++i)
{
medleft += Convert.ToInt32(datagridview_information.Rows[i].Cells[8]) - Convert.ToInt32(datagridview_medicine.Rows[i].Cells[4]);
datagridview_information.Rows[i].Cells[5].Value = Convert.ToString(medleft);
}
return medicineLeft();
}
You're going to have to give more code here, I have absolutely no idea what you're trying to do. Is medleft declared elsewhere?
Your medicineLeft() method is returning itself, meaning it'll run as an infinite loop and will probably throw a StackOverflow exception on this line:
datagridview_information.Rows[counterSelected].Cells[5].Value = medicineLeft();
Your medicineLeft method needs to return an integer - is it meant to return medleft? If so, changing it to return medleft; should fix this.
One easy solution would be to change the way you populate the DataGridView. If I were doing this, I would do the following:
Create a class object to store the data you want in your grid:
public class Medicine
{
public string BrandName { get; set; }
public string GenericName { get; set; }
<... add other properties ...>
}
Instantiate a collection of Medicine objects that you want to bind to the DataGridView.
public List<Medicine> GetMedicine(DataRowCollection rows)
{
List<Medicine> medicines = new List<Medicine>();
foreach (DataRow row in rows)
{
Medicine medicine = new Medicine();
medicine.BrandName = row["BrandName"] == null ? string.Empty : row["BrandName"].ToString();
medicine.GenericName = row["GenericName"] == null ? string.Empty : row["GenericName"].ToString();
//more rows here to populate Medicine object
//include the call to whatever methods are needed to populate the object
medicines.Add(medicine);
}
return medicines;
}
Bind the collection to the DataGridView
datagridview_information.DataSource = GetMedicines(dt.Rows);
I find it easy to create the DataGridView control on the form, set the columns in the designer, and set the AutoGenerateColumns property to false in code so that the grid appears as I wish. It is up to you how you want to handle that.
I need to display values like "Surreptitiously" and "Discreetly" in a comboBox but thereafter be able to set the comboboxes' SelectedItem based on the underlying DB values for those words (e.g., "S" and "D").
I reckon I can use the comboBoxes' DisplayMember and ValueMember properties for this somehow, but can I subsequently do something analagous to the following with the actual (valuemember) values:
comboBoxAdverbs.SelectedIndex = comboBoxAdverbs.Items.IndexOf(weirdAdverbs[CURRENT_ADVERB]);
As "weirdAdverbs[CURRENT_ADVERB]" contains the values like "S" and "D" it, of course, doesn't find and set the SelectedIndex when the comboBox contains the values "Surreptitiously" and "Discreetly"
If I set the combobox Item Tag value to "S" and "D" (assuming that's possible), I can loop through those values, but I'm hoping there's a one-line way of doing it similar to the "IndexOf()" above.
I use a template class for this and it comes in pretty darn handy. The combo box will show whatever text you want and you can store a value with it.
public class cboItem<T>
{
public cboItem(string name, T value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; set; }
public T Value { get; set; }
public override string ToString()
{
return Name == null ? "" : Name;
}
}
Combo box items can be anything, including classes/structs. By default it will use the ToString() implementation to display items, but if you populate a set of objects you can use DisplayMember and ValueMember to great effect.
As a simple example to give you some ideas we'll bind the combo box to a set of KeyValuePair instances for your weird verb codes and their descriptive names. Alternatively you can use linq to compose anonymous types, or create your own suitable classes/structs.
private void populateCombo()
{
comboBoxAdverbs.Items.Clear();
comboBoxAdverbs.Items.Add( new Tuple<string, string>( "S", "Surreptitiously" ) );
comboBoxAdverbs.Items.Add( new Tuple<string, string>( "D", "Discreetly" ) );
comboBoxAdverbs.DisplayMember = "Item2";
}
Then in your code where you want to select an item matching a provided code: (I.e. "D")
var item = comboBoxAdverbs.Items
.OfType<Tuple<string,string>>()
.FirstOrDefault(i => string.Compare(i.Item1, textBox1.Text, true) == 0);
if (item != null)
comboBoxAdverbs.SelectedItem = item;
This attempts to find the matching item by comparing the key against whatever input (in this case a textbox value) and if it finds a match, sets the SelectedItem to tell the combo box to select it.
** Edit: Whups, had originally use KeyValuePair which I didn't realize was a struct so no Null check-ability. Changed to Tuple (Essentially Pair)
What I found that works for me is to store the selectedindex value, after it's set, into the combobox's Tag property. Then, if the user attempts to change the selectedIndex when it is supposed to be in a "readonly" state, simply change it back to the selectedIndex value stored in the Tag property:
comboBoxPlatypusId.SelectedIndex = comboBoxPlatypusId.Items.IndexOf(DuckbillVals[Duckbill_PlatypusID]);
comboBoxPlatypusId.Tag = comboBoxPlatypusId.SelectedIndex;
...
private void comboBoxFunnyMammals_SelectedValueChanged(object sender, EventArgs e) {
var cb = sender as ComboBox;
if (cb != null)
{
int validSelection = Convert.ToInt32(cb.Tag);
if (cb.SelectedIndex != validSelection) {
cb.SelectedIndex = validSelection;
}
}
}
I have quite a few radiobuttonLists in my ASP.net webform. I am dynamically binding them using the method shown below:
public static void PopulateRadioButtonList(DataTable currentDt, RadioButtonList currentRadioButtonList, string strTxtField, string txtValueField,
string txtDisplay)
{
currentRadioButtonList.Items.Clear();
ListItem item = new ListItem();
currentRadioButtonList.Items.Add(item);
if (currentDt.Rows.Count > 0)
{
currentRadioButtonList.DataSource = currentDt;
currentRadioButtonList.DataTextField = strTxtField;
currentRadioButtonList.DataValueField = txtValueField;
currentRadioButtonList.DataBind();
}
else
{
currentRadioButtonList.Items.Clear();
}
}
Now, I want to Display only the first Letter of the DataTextField for the RadioButton Item Text.
For example if the Value is Good I just want to Display G. If it Fair I want to display F.
How do I do this in C#
Thanks
You can't do what you want when you do the binding, so you have 2 options:
Modify the data you get from the table, before you do the binding.
After binding, go through each item and modify its Text field.
So, it you want to display "only the first Letter of the DataTextField for the RadioButton Item Text", you can do:
currentRadioButtonList.DataSource = currentDt;
currentRadioButtonList.DataTextField = strTxtField;
currentRadioButtonList.DataValueField = txtValueField;
currentRadioButtonList.DataBind();
foreach (ListItem item in currentRadioButtonList.Items)
item.Text = item.Text.Substring(0, 1);
If I misunderstood you and you want to display the first letter of the Value field, you can replace the last two lines with:
foreach (ListItem item in currentRadioButtonList.Items)
item.Text = item.Value.Substring(0, 1);
You could add a property to the type that is being bound (the one that contains Good, Fair, etc.) and bind to this property. If you will always be using the first letter, you could make it like so (adding in null checks, of course):
public string MyVar { get; set; }
public string MyVarFirstChar
{
get { return MyVar.Substring(0, 2); }
}