I want to set a value for a cell that is actually a comboboxcell. I done it for my another project but now the same way, doesnt work!!
here is my code
//dgExcel is my datagridview
var cmb = (DataGridViewComboBoxColumn)dgExcel.Columns[1];
cmb.DataSource = sucTurleri; //its a list
cmb.DisplayMember = "SucTuru";
cmb.ValueMember = "Id";
and this code is adding row to the grid
var Konumlar = ExcelYardimcisi.KonumlariExceldenAl(dg.FileName);
foreach (var konum in Konumlar)
{
dgExcel.Rows.Add(konum.KonumAdi, sucTurleri[0].SucTuru, DateTime.Now.ToShortDateString());
}
but i got an error and i used this
foreach (var konum in Konumlar)
{
dgExcel.Rows.Add(konum.KonumAdi, null, DateTime.Now.ToShortDateString());
DataGridViewComboBoxCell cbox = (DataGridViewComboBoxCell)dgExcel.Rows[dgExcel.Rows.Count - 1].Cells[1];
cbox.Value = sucTurleri[0].SucTuru;
}
and the error is
Your data binding part is pretty OK. The problem is with dgExcel.Rows.Add() method.
Here is a sample code:
List<Item> items = new List<Item>();
items.Add(new Item() { Name = "One", Id = 1 });
items.Add(new Item() { Name = "Two", Id = 2 });
var cbo = dataGridView1.Columns[1] as DataGridViewComboBoxColumn;
cbo.DataSource = items;
cbo.ValueMember = "Id";
cbo.DisplayMember = "Name";
dataGridView1.Rows.Add("test", items[1].Id);
...
public class Item
{
public string Name { get; set; }
public int Id { get; set; }
}
Because the DataGridViewComboBoxColumn is data bound, you have to set the value by ValueMember, in my case items[1].Id. You have to to this in your code as well.
Related
I need to populate a DataGridView with items from a List.
I need the first row of the GridView populated with the items from the String List and i need to do some processing on the items in the GridView one by one and add the result to the second row(String).
Currently im Binding the DataGridView like this
dataGridView1.DataSource = mylist.ConvertAll(x => new { Value = x });
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
I need to predefine the column name add strings in the first row,process these strings one by one and update the second column..what is the best way to do this?
here is your solution,
dgvDataViewer.ColumnCount = 1;
dgvDataViewer.Columns[0].Name = "Language";
string[] row = new string[] { "C#" };
dgvDataViewer.Rows.Add(row);
row = new string[] { "C++" };
dgvDataViewer.Rows.Add(row);
row = new string[] { "C" };
dgvDataViewer.Rows.Add(row);
DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
cmb.HeaderText = "HeaderText";
cmb.Name = "Name";
cmb.FlatStyle = FlatStyle.System;
dgvDataViewer.Columns.Add(cmb);
DataGridViewComboBoxCell dgvcbc = (DataGridViewComboBoxCell)dgvDataViewer.Rows[0].Cells[1];
dgvcbc.Items.Add("Apple");
dgvcbc.Items.Add("Google");
dgvcbc.Items.Add("Apache");
dgvcbc.Items.Add("Microsoft");
Hope this will help you for your solution.
First you need to build your columns either programmatically or you can use the designer - that is up to you. I will code all of it for the sake of showing the entire example:
private DataGridView dgNew;
public MyForm()
{
InitializeComponent();
MyInitializeComponent();
}
private void MyInitializeComponent()
{
dgNew = new DataGridView();
var txtCol = new DataGridViewTextBoxColumn
{
HeaderText = "Column1",
Name = "Column1",
DataPropertyName = "Value"
};
dgNew.Columns.Add(txtCol);
txtCol = new DataGridViewTextBoxColumn
{
HeaderText = "Column2",
Name = "Column2",
};
dgNew.Columns.Add(txtCol);
var listOfStrings = new List<string> {"one", "two", "three"};
dgNew.DataSource = listOfStrings.ConvertAll(x => new { Value = x }); ;
dgNew.Location = dg.Location;
dgNew.Parent = this;
this.Load += Form_Load;
}
private void Form_Load(object sender, EventArgs e)
{
// Iterate over the rows, ignoring the header row
foreach (var row in dgNew.Rows.OfType<DataGridViewRow>().Where(a => a.Index != -1))
{
var col1Value = row.Cells["Column1"].Value?.ToString();
var col2Cell = row.Cells["Column2"];
if (col1Value == null) continue;
switch (col1Value)
{
case ("one"):
col2Cell.Value = "row1, col2 val";
break;
case ("two"):
col2Cell.Value = "row2, col2 val";
break;
case ("three"):
col2Cell.Value = "row1, col3 val";
break;
}
}
}
public void InsertHobbies()
{
//foreach(object obj in chkEmpHobbyList.Controls)
//{
// CheckBox chkbox = (CheckBox)obj;
// if(chkbox.Checked)
// {
// hobby objhobby = new hobby();
// objhobby.insertHobby((Convert.ToInt32(chkbox.ID)),empid);
// }
//}
foreach (ListItem listItem in chkEmpHobbyList.Items)
{
if (listItem.Selected)
{
hobby objhobby = new hobby();
objhobby.insertHobby((Convert.ToInt32(/what to give/)), empid);
}
}
}
/***aspx code****/
<asp:CheckBoxList ID="chkEmpHobbyList" runat="server">
</asp:CheckBoxList>
/**bind list with database **/
public List<hobby> GetHobbies()
{
DBlist obj = new DBlist();
DataSet ds = obj.getdata("str_gethobby", null);
List<hobby> hobbies = new List<hobby>();
foreach (DataRow orow in ds.Tables[0].Rows)
{
hobby dlist = new hobby();
dlist.HobbyName = orow["hobby_name"].ToString();
dlist.Hobbyvalue = int.Parse(orow["id"].ToString());
hobbies.Add(dlist);
}
return hobbies;
}
/****/
hobby dlist = new hobby();
List<hobby> hobbies = dlist.GetHobbies();
chkEmpHobbyList.DataSource = hobbies;
chkEmpHobbyList.DataTextField = "HobbyName";
chkEmpHobbyList.DataValueField = "Hobbyvalue";
chkEmpHobbyList.DataBind();
I want to loop through asp.net control checkboxlist and retrieve value of check items so that I can store id in database. How would I get Id of checked checkboxes?
You can iterate over your CheckBoxList and get Value/Text like this:
for (int i = 0; i < chkEmpHobbyList.Items.Count; i++)
{
if (chkEmpHobbyList.Items[i].Selected)
{
string value=chkEmpHobbyList.Items[i].Value;//it will return Value, You can also get .Text
}
}
Hope it helps!
I'm having trouble setting the value of DataGridViewComboBoxCell. The datagridview column is bound with choices/values but when I attempt either dgv.Rows.Add with specified column values for the comboBoxCells OR setting the cell's value seperately, it generates the "DataGridViewComboBoxCell value is not valid" error. If I add a row with blank values for those column, the choices display in the combo just fine.
I have a dialog that is passed an arraylist of a simple object, NDCRecord.
public class NDCRecord
{
public string NDCcode = "";
public string UnitQuantity = "";
public string UnitOfMeasurement = "";
public string Type = "";
public string Number = "";
}
In the dialog a datagrid is created programmatically and then is repopulated.
public NationalDrugCodesForm(ref ArrayList ndcRecordsIn)
{
InitializeComponent();
ndcRecords = ndcRecordsIn;
SetupDataGridViewColumns();
PopulateForm();
}
Setup:
private void SetupDataGridViewColumns()
{
// -----------------------------------------------------
// Add/Del column
// -----------------------------------------------------
DataGridViewButtonColumn dgvbcAddRemove = new DataGridViewButtonColumn();
dgvbcAddRemove.HeaderText = "Add";
dgvbcAddRemove.Text = "Add";
dgvbcAddRemove.Name = "Add";
DataGridViewCellStyle addButtonStyle = new DataGridViewCellStyle();
addButtonStyle.BackColor = Color.Blue;
addButtonStyle.ForeColor = Color.White;
dgvbcAddRemove.HeaderCell.Style = addButtonStyle;
dgvNDC.Columns.Add(dgvbcAddRemove);
// -----------------------------------------------------
// Additional Columns
// -----------------------------------------------------
dgvNDC.Columns.Add("NDCCode", "NDC Code");
dgvNDC.Columns.Add("UnitQuantity", "Unit Quantity");
DataGridViewComboBoxColumn unitOfMeasurement = new DataGridViewComboBoxColumn();
unitOfMeasurement.HeaderText = "Unit Of Measurement";
unitOfMeasurement.Name = "UnitOfMeasurement";
dgvNDC.Columns.Add(unitOfMeasurement);
DataGridViewComboBoxColumn type = new DataGridViewComboBoxColumn();
type.HeaderText = "Type";
type.Name = "Type";
dgvNDC.Columns.Add(type);
dgvNDC.Columns.Add("Number", "Prescription Number");
AddLine("Del", "", "", "", "", "");
BindUnitOfMeasurement((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["UnitOfMeasurement"]);
BindType((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["Type"]);
}
The AddLine function:
private void AddLine(string buttonLabel, string ndcCode, string unitQuantity, string unitOfMeasurement, string type, string rxNumber)
{
dgvNDC.Rows.Add(new object[] { buttonLabel, ndcCode, unitQuantity, unitOfMeasurement, type, rxNumber });
}
The binding functions:
private void BindUnitOfMeasurement(DataGridViewComboBoxCell cb)
{
string[] Values = { "F2", "GR", "ME", "ML", "UN" };
string[] Choices = { "F2 - International Unit", "GR - Gram", "ME - Milligram", "ML - Milliliter", "UN - Unit" };
ControlManip.DataBindDDL(cb, Choices, Values);
}
private void BindType(DataGridViewComboBoxCell cb)
{
string[] Values = { "XZ", "VY" };
string[] Choices = { "XZ - Prescription Number", "VY - Link Sequence Number" };
ControlManip.DataBindDDL(cb, Choices, Values);
cb.Value = "XZ";
}
public static void DataBindDDL(ref ComboBox cb, string[] Choices, string[] Values)
{
DataTable dt = new DataTable();
dt.Columns.Add("Choice");
dt.Columns.Add("Value");
if (Choices.Length != Values.Length)
{
throw new Exception("Number of Choices and Values do not match!");
}
else
{
dt.Rows.Add(new object[] { "", "" });
for (int i = 0; i < Choices.Length; i++)
{
if (Choices[i] is object && Values[i] is object)
{
dt.Rows.Add(new object[] { Choices[i], Values[i] });
}
}
cb.DataSource = dt;
cb.DisplayMember = "Choice";
cb.ValueMember = "Value";
}
}
Populate the form:
private void PopulateForm()
{
if (ndcRecords == null || ndcRecords.Count == 0)
return;
dgvNDC.Rows.Clear();
foreach(NDCRecord record in ndcRecords)
{
AddLine("Del", record.NDCcode, record.UnitQuantity, record.UnitOfMeasurement, record.Type, record.Number);
}
}
The problem was that I was binding individual CELLs instead of the COLUMNS that contained the drop-down box. I had inserted bind methods where the "Add" button was clicked that made it appear as though adding a row with blank values still resulted in populated dropdowns. But adding a row with values specified caused an error because the row's dropdown columns had nothing in their collection yet. So here are the important modifications to the code:
In SetupDataGridViewColumns instead of
BindUnitOfMeasurement((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["UnitOfMeasurement"]);
BindType((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["Type"]);
use
BindUnitOfMeasurement((DataGridViewComboBoxColumn)dgvNDC.Columns["UnitOfMeasurement"]);
BindType((DataGridViewComboBoxColumn)dgvNDC.Columns["Type"]);
and modify the binding methods appropriately. Then, you can add a row with blank values for the combo, or specified values, and it will work (below one of them has a value specified for default, the other is left blank for the user to select from)
AddLine("Del", "", "", "", "XZ", "");
Also, I'm not sure if this was necessary but in the course of experimenting I also added this for each combobox column:
type.ValueType = typeof (string);
I have combobox in my windows forms app and I want it to have values on particular options.
Now I can only put an option, and when I choose it - I can get it via
combobox.text
My target is to list filenames in combobox and have paths to them in values.
Example: Text is= "option1" value which it contains is = "value1", how to do it?
I saw a few topics about it, but they are about 2 years old, maybe something changed, cause these solutions were not so friendly : ]
UPDATE
I've got one issue with your solution, Mahmoud Gamal : )
I'm doing it this way:
List<Foo> combo3data = new List<Foo>();
categories = Directory.GetDirectories(#"C:\banners\categories\");
// There are 3 different paths in categories[] array (category1, category2 and 3)
Foo categoryInsert = new Foo();
foreach (string s in categories)
{
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
comboBox3.DataSource = combo3data;
comboBox3.ValueMember = "path";
comboBox3.DisplayMember = "name";
After that my comboBox3 has 3 available options (correct) but all of them are the same (same as option #1) - why is that?
You are looking for the two properties:
ValueMember.
DisplayMember.
In your case, you have to set the combobox's ValueMember property to value1 and the DisplayMember property to option1.
Update: The following is an exmple of how you can populate the items of a combobox from list of some entity Foo:
public class Foo(){
public string Id { get; set; }
public string Name { get; set; }
}
var ds = new List<Foo>(){
new Foo { Id = "1", Name = "name1" },
new Foo { Id = "2", Name = "name2" },
new Foo { Id = "3", Name = "name3" },
new Foo { Id = "4", Name = "name4" },
};
comboboxName.DataSource = ds;
comboboxName.ValueMember = "Id";
comboboxName.DisplayMember = "Name";
Update2: That's because you are adding the same object each time. In the following block of your code:
Foo categoryInsert = new Foo();
foreach (string s in categories)
{
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
Each time The foreach iterate over the categories, all what it does, is changing the same object categoryInsert's values path and name not creating a new one. Thus, you end up with the same object added in each iteration to the combo3data. What you need is create a new Foo object inside the foreach itself each time, i.e: move the Foo categoryInsert = new Foo(); inside the foreach loop. Something like:
foreach (string s in categories)
{
Foo categoryInsert = new Foo();
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
use comboBox.Text to set or get the text associated with this combobox.
for Values use comboBox.ValueMember for the actual value for the items in the ListControl
or you could also store the values in the comboBox.Tag
i am using a datagridview in that i am using a datagridviewcomboboxcolumn, comboboxcolumn is displaying text but the problem is i want to select the first item of comboboxcolumn by default how can i do this
DataGridViewComboBoxColumn dgvcb = (DataGridViewComboBoxColumn)grvPackingList.Columns["PackingUnits"];
Globals.G_ProductUtility G_Utility = new Globals.G_ProductUtility();
G_Utility.addUnittoComboDGV(dgvcb);
DataSet _ds = iRawMaterialsRequest.SelectBMR(bmr_ID, branch_ID, "PACKING");
grvPackingList.DataSource = _ds.Tables[0];
int i = 0;
foreach (DataRow dgvr in _ds.Tables[0].Rows)
{
grvPackingList.Rows[i].Cells["Units"].Value = dgvr["Units"].ToString();
i++;
}
The values available in the combobox can be accessed via items property
row.Cells[col.Name].Value = (row.Cells[col.Name] as DataGridViewComboBoxCell).Items[0];
the best way to set the value of a datagridViewComboBoxCell is:
DataTable dt = new DataTable();
dt.Columns.Add("Item");
dt.Columns.Add("Value");
dt.Rows.Add("Item1", "0");
dt.Rows.Add("Item1", "1");
dt.Rows.Add("Item1", "2");
dt.Rows.Add("Item1", "3");
DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
cmb.DefaultCellStyle.Font = new Font("Tahoma", 8, FontStyle.Bold);
cmb.DefaultCellStyle.ForeColor = Color.BlueViolet;
cmb.FlatStyle = FlatStyle.Flat;
cmb.Name = "ComboColumnSample";
cmb.HeaderText = "ComboColumnSample";
cmb.DisplayMember = "Item";
cmb.ValueMember = "Value";
DatagridView dvg=new DataGridView();
dvg.Columns.Add(cmb);
cmb.DataSource = dt;
for (int i = 0; i < dvg.Rows.Count; i++)
{
dvg.Rows[i].Cells["ComboColumnSample"].Value = (cmb.Items[0] as
DataRowView).Row[1].ToString();
}
It worked with me very well
If I had known about doing it in this event, it would have saved me days of digging and
trial and errors trying to get it to set to the correct index inside the CellEnter event.
Setting the index of the DataGridViewComboBox is the solution I have been looking for.....THANKS!!!
In reviewing all the issues other coders have been experiencing with trying to set
the index inside of a DataGridViewComboBoxCell and also after looking over your code,
all that anyone really needs is:
1. Establish the event method to be used for the "EditingControlShowing" event.
2. Define the method whereby it will:
a. Cast the event control to a ComboBox.
b. set the "SelectedIndex" to the value you want.
In this example I simply set it to "0", but you'd probably want to apply so real life logic here.
Here's the code I used:
private void InitEvents()
{
dgv4.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler( dgv4EditingControlShowing );
}
private void dgv4EditingControlShowing( object sender, DataGridViewEditingControlShowingEventArgs e )
{
ComboBox ocmb = e.Control as ComboBox;
if ( ocmb != null )
{
ocmb.SelectedIndex = 0;
}
}
If DataGridViewComboBoxCell already exist:
DataTable dt = new DataTable();
dt.Columns.Add("Item");
dt.Columns.Add("Value");
dt.Rows.Add("Item 1", "0");
dt.Rows.Add("Item 2", "1");
dt.Rows.Add("Item 3", "2");
dt.Rows.Add("Item 4", "3");
for (int i = 0; i < dvg.Rows.Count; i++)
{
DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dvg.Rows[i].Cells[1];
comboCell.DisplayMember = "Item";
comboCell.ValueMember = "Value";
comboCell.DataSource = dt;
};
I've had some real trouble with ComboBoxes in DataGridViews and did not find an elegant way to select the first value. However, here is what I ended up with:
public static void InitDGVComboBoxColumn<T>(DataGridViewComboBoxCell cbx, List<T> dataSource, String displayMember, String valueMember)
{
cbx.DisplayMember = displayMember;
cbx.ValueMember = valueMember;
cbx.DataSource = dataSource;
if (cbx.Value == null)
{
if(dataSource.Count > 0)
{
T m = (T)cbx.Items[0];
FieldInfo fi = m.GetType().GetField(valueMember, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
cbx.Value = fi.GetValue(m);
}
}
}
It basically sets the .Display and .ValueMember properties of the DataGridViewComboBoxCell and uses a List as DataSource. It then takes the first item, and uses reflection to get the value of the member that was used as ValueMember and sets the selected value via .Value
Use it like this:
public class Customer
{
private String name;
public String Name
{
get {return this.name; }
set {this.name = value; }
}
private int id;
public int Id
{
get {return this.id; }
set {this.id = value; }
}
}
public class CustomerCbx
{
private String display;
public String Display
{
get {return this.display; }
set {this.display = value; }
}
private Customer value;
public Customer Value
{
get {return this.value; }
set {this.value = value; }
}
}
public class Form{
private void Form_OnLoad(object sender, EventArgs e)
{
//init first row in the dgv
if (this.dgv.RowCount > 0)
{
DataGridViewRow row = this.dgv.Rows[0];
DataGridViewComboBoxCell cbx = (DataGridViewComboBoxCell)row.Cells[0];
Customer c1 = new Customer(){ Name = "Max Muster", ID=1 };
Customer c2 = new Customer(){ Name = "Peter Parker", ID=2 };
List<CustomerCbx> custList = new List<CustomerCbx>()
{
new CustomerCbx{ Display = c1.Name, Value = c1},
new CustomerCbx{ Display = c2.Name, Value = c2},
}
InitDGVComboBoxColumn<CustomerCbx>(cbx, custList, "display", "value");
}
}
}
}
It seems pretty hacky to me, but I couldn't find any better way so far (that also works with complex objects other than just Strings). Hope that will save the search for some others ;)
You need to set the Items for the new cell. This must be auto done by the column when creating a new row from the UI.
var cell = new DataGridViewComboBoxCell() { Value = "SomeText" };
cell.Items.AddRange(new String[]{"SomeText", "Abcd", "123"});
something different worked for me what i did is to simply set the value of dtataGridComboBox when ever new record is added bu user with 'userAddedRow' event. For the first row I used the code in constructor.
public partial class pt_drug : PatientDatabase1_3._5.basic_templet
{
public pt_drug()
{
InitializeComponent();
dataGridView_drugsDM.Rows[0].Cells[0].Value = "Tablet";
}
private void dataGridView_drugsDM_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
dataGridView_drugsDM.Rows[dataGridView_drugsDM.RowCount - 1].Cells[0].Value = "Tablet";
}
}
Here the solution I have found : select the cell you are interested in so you can cast it to a combobox.
this.Invoke((MethodInvoker)delegate
{
this.dataGridView1.CurrentCell = dataGridView1.Rows[yourRowindex].Cells[yourColumnIndex];
this.dataGridView1.BeginEdit(true);
ComboBox comboBox = (ComboBox)this.dataGridView1.EditingControl;
comboBox.SelectedIndex += 1;
});