I have a combobox farmRegion that I fill in this way
private void fillRegionData() {
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Description", typeof(string));
farmRegion.ValueMember = "ID";
farmRegion.DisplayMember = "Description";
farmRegion.SelectedValue = "ID";
for (int i = 0; i < StaticData.RegionNames.Count; i++)
{
dt.Rows.Add(StaticData.RegionValues[i], StaticData.RegionNames[i]);
}
farmRegion.DataSource = dt;
}
where StaticData.RegionNames is:
public static List<string> RegionNames = new List<string>() { "Select Region", "EASTERN", "WESTERN", "NORTHERN", "EASTERN2", "NORTHERN", "MIDDLE" };
and StaticDate.RegionValues is
public static List<string> RegionValues = new List<string>() { "-10", "1", "2", "3", "4", "5", "6" };
when I save the form, I save the text of the combobox, not the value (this is a requirement issue).
now I want to reload the comboxbox again.
I already know the text but I need to make the combobox fires and the option text is already selected.
I tried this:
farmRegion.Text = myText
but still the first option is selected.
Before setting the text farmRegion.Text = myText put a break point and checks the combobox datasource, and ensure myText is present in combobox.
If you handled any events of combobox put a break point on that events and check what happend after the execution of farmRegion.Text = myText statement.
These two steps doen't solve your issue then find out the index of your text value as
int index = farmRegion.FindString(myText);
farmRegion.SelectedIndex = index;
You can try this
farmRegion.SelectedIndex = farmRegion.FindStringExact(myText)
Another Approach:
Note: This may throw argumentexception if the item was not found.
farmRegion.SelectedIndex = farmRegion.Items.IndexOf(myText);
try like this,
DataRow[] drs = ((DataTable)cmb.DataSource).Select("Description='" + myText + "'");
if (drs.Length > 0)
{
cmb.SelectedValue = drs[0]["ID"].ToString();
}
else
{
//Value not found
}
EDITED:
Sometime when you set the text of combobox will not return the value of ValueMember from SelectedValue it may return null and SelectedIndex may return -1.
Related
I have a checkedListBox on a winform.
I fill the check box with some code see below.
All works well.
Now I need to get the value of the checked items. I am having some issues.
When I do the foreach(var item in clbtest.CheckedItems)
I get this when doing a Immediate window... ? item
{ Text = "Depos", Value = "Q:\\Scanning Department\\_DT SEARCH INDEXES\\Depos" }
Text: "Depos"
Value: "Q:\\Scanning Department\\_DT SEARCH INDEXES\\Depos"
I don't know how to get at the Value field. I have tried several ways but nothing seems to work.
private void FillIndexes()
{
string stext = cblIndexToSearch.Text;
cblIndexToSearch.Items.Clear();
cblIndexToSearch.Text = "";
cblIndexToSearch.DisplayMember = "Text";
cblIndexToSearch.ValueMember = "Value";
foreach (var item in indexlist)
{
cblIndexToSearch.Items.Insert(0,
new { Text = item.indexName, Value = #item.indexPath });
}
}
Hope this helps. Just create a checklistbox named "checkedListBox1" and the code should work. I detailed a little on what it does.
checkedListBox1.Items.Clear();
checkedListBox1.Text = "";
checkedListBox1.DisplayMember = "Text";
checkedListBox1.ValueMember = "Value";
checkedListBox1.Items.Insert(0,
new { Text = "Rawr", Value = "Whatever 2011"});
string temp = checkedListBox1.Items[0].ToString(); //gets the string of the item. (switch 0 to the index you want)
string string_Value = temp.Split(new string[] { "Value = " }, StringSplitOptions.None)[1]; //splits the string by the value part and returns the string value.
string_Value = string_Value.Substring(0, string_Value.Length - 2); ; //removes the last 2 characters since they are not part of the value.
//you now have the value in string form.
I have a asp combo box inside update panel with autopost back set to true.
On page Load I fill combo box as
public DataTable getProductDetails()
{
MasterAllocationDB dataHandler = new MasterAllocationDB();
DataTable dataBoxType = null;
DataRow row = null;
try
{
dataBoxType = dataHandler.GetBoxType();
if (dataBoxType != null && dataBoxType.Rows.Count > 0)
{
row = dataBoxType.NewRow();
row["Product"] = "--Select--";
dataBoxType.Rows.InsertAt(row,0);
row = dataBoxType.NewRow();
row["Product"] = "Other";
dataBoxType.Rows.InsertAt(row, dataBoxType.Rows.Count);
}
}
catch (Exception ex)
{
LogHandler.LogMessageToFile(ex, LogMode.Fatal);
}
return dataBoxType;
}
Also I have a onselectedindexchanged event binded
protected void productComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
string json = null;
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row = null;
var s = this.productComboBox.SelectedValue;
try
{
int totalNoOfItems = this.productComboBox.Items.Count;
// Make sure that Index are between "select a value" and "Other"
if (this.productComboBox.SelectedIndex > 0 && this.productComboBox.SelectedIndex < totalNoOfItems - 1)
{
//code here
}
json = new JavaScriptSerializer().Serialize(rows);
}
catch (Exception ex)
{
LogHandler.LogMessageToFile(ex, LogMode.Fatal);
}
}
As you can see I have added 2 extra rows besides the rows fetched from DB.The data rows are binding properly as I can see the same in outputed combo box values
After running I noticed that whenever I select "other" the text inside combo box gets changed
to "--select--" and control never reaches onselectedindexchanged
It works finely for all the other cases. What could be the reason?
Ok I sorted it out.
The problem is that I have only set text for the combo box not value for options.
Changed the code as
row["Product"] = "--Select--";
row["ProductID"] = "0";
row["Product"] = "Other";
row["ProductID"] = "10";
ProductId gives the value for combobox.
Happy coding
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 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;
});
I seem to be running around in circles and have been doing so in the last hours.
I want to populate a datagridview from an array of strings. I've read its not possible directly, and that I need to create a custom type that holds the string as a public property. So I made a class:
public class FileName
{
private string _value;
public FileName(string pValue)
{
_value = pValue;
}
public string Value
{
get
{
return _value;
}
set { _value = value; }
}
}
this is the container class, and it simply has a property with the value of the string. All I want now is that string to appear in the datagridview, when I bind its datasource to a List.
Also I have this method, BindGrid() which I want to fill the datagridview with. Here it is:
private void BindGrid()
{
gvFilesOnServer.AutoGenerateColumns = false;
//create the column programatically
DataGridViewTextBoxColumn colFileName = new DataGridViewTextBoxColumn();
DataGridViewCell cell = new DataGridViewTextBoxCell();
colFileName.CellTemplate = cell; colFileName.Name = "Value";
colFileName.HeaderText = "File Name";
colFileName.ValueType = typeof(FileName);
//add the column to the datagridview
gvFilesOnServer.Columns.Add(colFileName);
//fill the string array
string[] filelist = GetFileListOnWebServer();
//try making a List<FileName> from that array
List<FileName> filenamesList = new List<FileName>(filelist.Length);
for (int i = 0; i < filelist.Length; i++)
{
filenamesList.Add(new FileName(filelist[i].ToString()));
}
//try making a bindingsource
BindingSource bs = new BindingSource();
bs.DataSource = typeof(FileName);
foreach (FileName fn in filenamesList)
{
bs.Add(fn);
}
gvFilesOnServer.DataSource = bs;
}
Finally, the problem: the string array fills ok, the list is created ok, but I get an empty column in the datagridview. I also tried datasource= list<> directly, instead of = bindingsource, still nothing.
I would really appreciate an advice, this has been driving me crazy.
Use a BindingList and set the DataPropertyName-Property of the column.
Try the following:
...
private void BindGrid()
{
gvFilesOnServer.AutoGenerateColumns = false;
//create the column programatically
DataGridViewCell cell = new DataGridViewTextBoxCell();
DataGridViewTextBoxColumn colFileName = new DataGridViewTextBoxColumn()
{
CellTemplate = cell,
Name = "Value",
HeaderText = "File Name",
DataPropertyName = "Value" // Tell the column which property of FileName it should use
};
gvFilesOnServer.Columns.Add(colFileName);
var filelist = GetFileListOnWebServer().ToList();
var filenamesList = new BindingList<FileName>(filelist); // <-- BindingList
//Bind BindingList directly to the DataGrid, no need of BindingSource
gvFilesOnServer.DataSource = filenamesList
}
may be little late but useful for future. if you don't require to set custom properties of cell and only concern with header text and cell value then this code will help you
public class FileName
{
[DisplayName("File Name")]
public string FileName {get;set;}
[DisplayName("Value")]
public string Value {get;set;}
}
and then you can bind List as datasource as
private void BindGrid()
{
var filelist = GetFileListOnWebServer().ToList();
gvFilesOnServer.DataSource = filelist.ToArray();
}
for further information you can visit this page Bind List of Class objects as Datasource to DataGridView
hope this will help you.
I know this is old, but this hung me up for awhile. The properties of the object in your list must be actual "properties", not just public members.
public class FileName
{
public string ThisFieldWorks {get;set;}
public string ThisFieldDoesNot;
}
Instead of create the new Container class you can use a dataTable.
DataTable dt = new DataTable();
dt.Columns.Add("My first column Name");
dt.Rows.Add(new object[] { "Item 1" });
dt.Rows.Add(new object[] { "Item number 2" });
dt.Rows.Add(new object[] { "Item number three" });
myDataGridView.DataSource = dt;
More about this problem you can find here: http://psworld.pl/Programming/BindingListOfString
Using DataTable is valid as user927524 stated.
You can also do it by adding rows manually, which will not require to add a specific wrapping class:
List<string> filenamesList = ...;
foreach(string filename in filenamesList)
gvFilesOnServer.Rows.Add(new object[]{filename});
In any case, thanks user927524 for clearing this weird behavior!!