I have a combobox with objects of Foo type, here is the Foo class:
public class Foo
{
public string name { get; set; }
public string path { get; set; }
}
The Foo.name is the displayed text in the combobox and Foo.path is the value of the selected option.
I want to delete an option from the combobox after some operation I made.
I've tried these ways:
1
comboBox2.Items.Remove(#comboBox2.Text);
2
comboBox2.Items.Remove(#comboBox2.SelectedValue.ToString());
3
Foo ToDelete = new Foo();
ToDelete.name = #comboBox2.Text;
ToDelete.path = #comboBox2.SelectedValue.ToString();
comboBox2.Items.Remove(ToDelete);
Nothing works for me. : / How to do this?
UPDATE
This is how I'm initializing my combobox:
string[] filePaths = Directory.GetFiles(sites.paths[comboBox1.SelectedIndex]);
List<Foo> combo2data = new List<Foo>();
foreach (string s in filePaths)
{
Foo fileInsert = new Foo();
fileInsert.path = s;
fileInsert.name = Path.GetFileName(s);
combo2data.Add(fileInsert);
}
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
comboBox2.Items.Remove(comboBox2.SelectedValue); will only remove from the combobox, not from the datasource bound to the combobox. You may remove it from the datasource and re-bind the datasource.
Use ComboBox.SelectedIndex property.
For example: let me have comboBox1 added to the form. In the delete button:
if (comboBox1.SelectedIndex >= 0)
comboBox1.Items.RemoveAt(comboBox1.SelectedIndex);
combox1.Remove(takes an object)
Object selectedItem = comboBox1.SelectedItem;
So you cna do it this way combox1.Remove(selectedItem);
Suppose you want to Remove Items by Index:
combo2data.RemoveAt(0); //Removing by Index from the dataSource which is a List
//Rebind
comboBox2.DataSource = null;
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
Suppose you want to Remove by seraching for a member value
Foo item = combo2data.Where(f => f.name.Equals("Tom")).FirstOrDefault();
if (item != null)
{
combo2data.Remove(item);
comboBox2.DataSource = null;
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
}
These 2 commands will remove an item from your data source.
list.Remove((Foo)comboBox1.SelectedItem);
or
list.Remove(list.Find(P=>P.name == comboBox1.SelectedText));
I think the secret is to first attribute null to the datasource and after rebind to a modified collection:
int idToRemove = 1;
var items = (cbx.DataSource as List<MyEntity>);
items.RemoveAll(v => v.Id == idToRemove);
rebindCombobox(cbx, items, "Name", "Id");
private void rebindCombobox(ComboBox cbx, IEnumerable<Object> items, String displayMember, String valueMember)
{
cbx.DataSource = null;
cbx.DisplayMember = displayMember;
cbx.ValueMember = valueMember;
cbx.DataSource = items;
}
Perhaps delete all items in the Combobox with
comboBox.Items.Clear();
Related
How can you set default value for combobox provided you get the value from table in database. I am thinking comparing the value with column [2]/destinationColumn to see which value in the table should be selected as default. This is my code so far which is wrong. Suggestion or an example code will be much appreciated. Thank you in advance guys.
string sqlLookupColumn = "SELECT LookUpColumnID, SOURCE_NAME FROM TB_LOOKUP_COLUMN ORDER BY SOURCE_NAME ASC";
DataSet dsColumn = databaseManager.GetData(sqlLookupColumn);
DataGridViewComboBoxColumn dgvCboColumn = new DataGridViewComboBoxColumn();
dgvCboColumn.Name = "DESTINATION_NAME";
dataGridView1.Columns.Add(dgvCboColumn);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewComboBoxCell cboDestinationColumns = (DataGridViewComboBoxCell)(row.Cells[3]);
cboDestinationColumns.DataSource = dsColumn.Tables[0];
string destinationColumn = row.Cells[2].Value.ToString();
cboDestinationColumns.DisplayMember = "SOURCE_NAME";
cboDestinationColumns.ValueMember = "LookUpColumnID";
if (destinationColumn == cboDestinationColumns.DisplayMember)
{
cboDestinationColumns.Selected = true;
}
}
Things that i can see wrong
1- Your loop on the GridView wont work, do the loop on the Dataset instead of the Gridview...
2- You are comparing destinationColumn with cboDestinationColumns.DisplayMember which = "SOURCE_NAME" and you want If destinationColumn = "InvoiceNo"
3- Add the to the combo items using for loop and .add method, and do your if statement their.
To add the items:
1st add this class
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
Then loop on the Dataset
for(int i=0;i<ds.Tables[0].Rows.Count;i++)
{
DataRow dr = ds.Tables[0].Rows[i];
ComboboxItem tmp= new ComboboxItem();
tmp.Text = dr["SOURCE_NAME"];
tmp.Value = dr["LookUpColumnID"];
cb.Items.Add(tmp);
if(dr["InvoiceNo"].ToString() =="")//Your condition here to set selected
cb.SelectedIndex = i;
}
Here is my code:
DataSet data = new DataSet();
data.ReadXml("data.xml");
DataGridView grid = new DataGridView();
var genreCboBoxItems = data.Tables[0].AsEnumerable().Select(genre => genre.Field<string>("genre")).Distinct().ToArray();
// TODO: Make is so the 'genre' column in grid is a combo box?
grid.DataSource = data.Tables[0];
grid.Dock = DockStyle.Fill;
this.Controls.Add(grid);
*edit: genreCboBoxItems
Try this: (not tested)
var column = new DataGridViewComboBoxColumn();
column.DataSource = data.Tables[0].AsEnumerable().
Select(genre => new { genre = genre.Field<string>("genre") }).Distinct();
column.DataPropertyName = "genre";
column.DisplayMember = "genre";
column.ValueMember = "genre";
grid.DataSource = data.Tables[0];
// Instead of the below line, You could use grid.Columns["genre"].Visible = false;
grid.Columns.Remove("genre");
grid.Columns.Add(column);
This might help you cast DataGridViewColumn to DataGridViewComboBox.
First create DataGridViewComboBoxColumn using designer with proper name. Then say you have a list of String list and other string values to bind to that datagridview then use this code:
Below code will bind a list to two DataGridViewTextBoxCell and a DataGridViewComboBoxCell. Note AllCriterias is a list with two string values and a list of string. DGVEligibilityCriteria is the grid name.
for (int i = 0; i < AllCriterias.Count; i++)
{
DataGridViewTextBoxCell Cmb1 = (DataGridViewTextBoxCell)DGVEligibilityCriteria.Rows[i].Cells[0];
Cmb1.Value = AllCriterias[i].Name;
DataGridViewTextBoxCell Cmb2 = (DataGridViewTextBoxCell)DGVEligibilityCriteria.Rows[i].Cells[1];
Cmb2.Value = AllCriterias[i].Type;
DataGridViewComboBoxCell Cmb = (DataGridViewComboBoxCell)DGVEligibilityCriteria.Rows[i].Cells[2];
foreach (var filtervalue in AllCriterias[i].FilterValues)
{
Cmb.Items.Add(filtervalue);
}
}
Need to display the fist index as default by setting selectindex property.
Use this code : Here "filterValues" is the name of the DataGridViewComboBoxCell which u created in the datagridview designer.
foreach (DataGridViewRow row in DGVEligibilityCriteria.Rows)
{
row.Cells["filterValues"].Value = (row.Cells["filterValues"] as DataGridViewComboBoxCell).Items[0];
}
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.
So I've been looking to set a default value for my combobox. I found a few things but none of them seem to work.
Actually, it works if I create a simple combobox and use comboBox1.SelectedIndex = comboBox1.Items.IndexOf("something") but once I dynamically generate the contents of the comboboxes, I can't get it to work anymore.
This is how I fill my combo box (located in the class's constructor);
string command = "SELECT category_id, name FROM CATEGORY ORDER BY name";
List<string[]> list = database.Select(command, false);
cbxCategory.Items.Clear();
foreach (string[] result in list)
{
cbxCategory.Items.Add(new ComboBoxItem(result[1], result[0]));
}
I can't seem to get it to work to set a default value, like if I place cbxCategory.SelectedIndex = cbxCategory.Items.IndexOf("New") below the above code, it won't work.
WinForms, by the way.
Thank you in advance.
cbxCategory.SelectedIndex should be set to an integer from 0 to Items.Count-1 like
cbxCategory.SelectedIndex = 2;
your
cbxCategory.SelectedIndex = cbxCategory.Items.IndexOf("New")
should return -1 as long as no ComboboxItem mutches the string ("New");
another solution though i don't like it much would be
foreach(object obj in cbxCategory.Items){
String[2] objArray = (String[])obj ;
if(objArray[1] == "New"){
cbxCategory.SelectedItem = obj;
break;
}
}
perhaps this also requires the following transformation to your code
foreach (string[] result in list)
{
cbxCategory.Items.Add(result);
}
I haven't tested the code and i am not sure about the casting to String[2] but something similar should work
It looks like you're searching the cbxCategory.Items collection for a string, but it contains items of type ComboBoxItem. Therefore the search will return -1.
You can use LINQ.
//string command = "SELECT category_id, name FROM CATEGORY ORDER BY name";
//List<string[]> list = database.Select(command, false);
// sample data...
List<string[]> list = new List<string[]> { new string[] { "aaa", "bbb" }, new string[] { "ccc", "ddd" } };
cbxCategory.Items.Clear();
foreach (string[] result in list)
{
cbxCategory.Items.Add(new ComboBoxItem(result[1], result[0]));
}
ComboBoxItem tmp = cbxCategory.Items.OfType<ComboBoxItem>().Where(x => x.ResultFirst == "bbb").FirstOrDefault();
if (tmp != null)
cbxCategory.SelectedIndex = cbxCategory.Items.IndexOf(tmp);
ComboBoxItem class:
class ComboBoxItem
{
public string ResultFirst { get; set; }
public string ResultSecond { get; set; }
public ComboBoxItem(string first, string second)
{
ResultFirst = first;
ResultSecond = second;
}
}
Here's my simple solution
var list = comboBox1.Items.Cast<string>().ToList();
cbxCategory.SelectedIndex = list.FindIndex(c => c.StartsWith("test"));
My solution:
int? defaultID = null;
foreach (DataRow dr in dataSource.Tables["DataTableName"].Rows)
{
if ((dr["Name"] != DBNull.Value) && ((string)dr["Name"] == "Default Name"))
{
defaultID = (int)dr["ID"];
}
}
if (defaultID != null) comboBox.SelectedValue = defaultID;
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
}