I'm currently working with C# and I have the following code to set a ComboBox column inside a DGV:
// Add the values of the combo box
dgvcbGeneric.DataSource = dtDataSource;
dgvcbGeneric.ValueMember = "ID";
dgvcbGeneric.DisplayMember = "Value";
dgvcbGeneric.DataPropertyName = strColumn;
dgvcbGeneric.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
dgvcbGeneric.DisplayStyleForCurrentCellOnly = true;
// vGenericCMB.SortMode = DataGridViewColumnSortMode.Automatic
dgvcbGeneric.DefaultCellStyle.NullValue = columns[strActualColumn].nullFormat;
// Add the new ComboBoxColumn of the DGV
dgvLink.Columns.Add(dgvcbGeneric);
All works fine, but the DGV only show the member value when the cell has the focus:
Someone can explain me why this issue is happening?
I found the error by myself. Basically in the DataSource of the DGV the column "Day" was of type "Byte" (tinyint in SQL).
When the code try to create the DataTable to fill up the DGV ComboBox Column; the ID type is "Integer".
The solution was check the DataType of the ID vs the column source. If are differents; throw an exception to check previously.
Related
I have a DataTable with some integer values (assume 0 => 'open', 1 => 'proceeding', 2 => 'free' etc.) and in a dgv I want to allow the user to change that value, but with a combobox and with string values. So I created to test this a simple winform app
public Form1()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("test");
dt.Rows.Add(1);
dt.Rows.Add(2);
DataTable source = new DataTable();
source.Columns.AddRange(new DataColumn[] { new DataColumn("Value", typeof(int)), new DataColumn("Display", typeof(string)) });
source.Rows.Add(0, "zero");
source.Rows.Add(1, "one");
source.Rows.Add(2, "two");
dataGridView1.DataSource = dt;
var testTextColumn = new DataGridViewComboBoxColumn();
testTextColumn.HeaderText = "Text";
testTextColumn.Name = "testText";
testTextColumn.DataSource = source;
testTextColumn.DisplayMember = "Display";
testTextColumn.ValueMember = "Value";
dataGridView1.Columns.Add(testTextColumn);
}
So far so good, I thought I could simply make the test column invisible and only have the testText column visible (in the final app), but how does one combine the to values, i.e. when I change something in the cb update the value of the datatable? I could do it by changeEvents, but that seems rather impractical. Is there some sort of databinding?
There are three (3) things wrong in your posted code to achieve what you describe.
1-The line of code…
dt.Columns.Add("test");
… is defaulting to a string value. Therefore, the combo box would throw a DataError when you try to bind the “Value” column from the source table. So, you need to specify the int type column in the data. Like…
dt.Columns.Add("test", typeof(int));
2- Before the code set the grids DataSource the code needs to specify that we do NOT want the grid to AutoGenerateColumns. Otherwise, we will end up with two columns. In addition, this grid property is NOT a displayed property in the “Designer.” You will need to set this property BEFORE you add the data source and you need to set this property in your code. Something like…
dataGridView1.AutoGenerateColumns = false;
3- When the code creates the combo box column, it never identifies “which” column in the grids DataSource we want to bind the combo box column to. That is the purpose of the columns DataPropertyName. So, you need to add this line of code in the combo box definition…
testTextColumn.DataPropertyName = "test";
Making these changes, should display only the combo box column.
creates a cell change event, then takes the number of the row you changed and you have access to the columns with the indexes ...
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentRow != null)
{
DataGridViewRow dgvRow = dataGridView1.CurrentRow;
// do what u want here like
int teste = Convert.ToInt32(dgvRow.Cells[1].Value);
}
}
I have a class derived from DataSet that I'm using as a datasource. My DataGridView has 8 columns of which 3 are multiple value choices that are edited with drop down combo boxes.
If I let the Datasource generate the columns for the DataGridView, then all of the column types are DataGridViewTextBoxColumn. However the DataGridView is populated with my original row values.
If I set AutoGenerateColumns to false and add my own column types to the DataGridView I can add DataGridViewComboBoxColumn for the 3 columns that require it. However, the DataSource, while it contains the row data, does not populate the rows of my DataGridView.
Obviously I want both things to happen. The rows need to be populated from the DataSource and the column need to be correctly editable from the DataGridView as DataGridViewComboBoxColumns. Why can't I have both? What am I doing wrong.
Please note this is not a question about using a DataSource to populate the items in a ComboBox.
code fragment
alarmDataSet = new AlarmDataSet(sAlarms);
gridView.AutoGenerateColumns = false;
gridView.DataSource = alarmDataSet;
gridView.DataMember = sAlarms;
another code fragment
cm = new DataGridViewComboBoxColumn();
cm.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
cm.HeaderText = ci.Name;
cm.Name = ci.DataName;
cm.MaxDropDownItems = 3;
cm.Items.Add("Once");
cm.Items.Add("Repeat");
cm.Items.Add("Off");
gridView.Columns.Add(cm);
Thanks
if you set
DataGridView.AutoGenerateColumns = false
Then You need to tell DataGeridView about which column of DataGridView bind to which column of DataSource (Property Name in case of list)
DataGridView.Column[0].DataPropertyName = "Column Name In Your DataSource That is bound to DataGridView Column 0"
I want to change a DataGridView cell value, and I can do it but cell value doesn't shown in DataGridView.
Here is the code;
Products.DataSource = productItems.DefaultView; // In here I assign the dataTable to the dataGridView.
foreach (DataGridViewRow row in Products.Rows)
{
if (row.Cells["ProductCode"].Value != null)
{
row.Cells["ProductName"].Value = sqlTrans.GetProductNameWithProductCode(row.Cells["ProductCode"].Value.ToString());
}
}
When I debug, I can see the value is assigned correctly but I can't see the value in dataGridView.
I already tried RefreshEdit, EndEdit, InvalidateCell and Refresh.
Thanks in advance.
EDIT:
After struggle few more hours, I solve this problem like this;
- After filling the DataTable with SqlDataAdapter, I added a new column named "ProductName" and then fill this column.
- And then I bound this DataTable into the DataGridView.
Background
I'm trying to set a column on my DGV up as a combobox. I've added all the columns to the gridview in the designer so all that is left is to bind them to the dataset.
The datatype of the Status column is varchar.
Question
However i keep getting a very unhelpful error message at run time. Am i doing something wrong?
DataGridViewComboBox Value is not valid.
The above error happens when setting the datasource of the dgv.
dataGridView1.DataSource = JoblistDataSet.Tables["Joblist"];
My Code
DataGridViewComboBoxColumn Column = (DataGridViewComboBoxColumn)dataGridView1.Columns["Status"];
Column.DataPropertyName = "Status";
DataGridViewComboBoxCell cbCell = (DataGridViewComboBoxCell)dataGridView1.Rows[0].Cells["Status"];
cbCell.Items.Add("New");
cbCell.Items.Add("Hold");
cbCell.Items.Add("Remove");
dataGridView1.DataSource = JoblistDataSet.Tables["Joblist"];
I think the problem is that you are populating DataGridViewComboBoxCell.Items for row index 0 instead of DataGridViewComboBoxColumn.Items which applies for all rows (hope you noticed Cell vs Column).
Use something like this instead
var statusColumn = (DataGridViewComboBoxColumn)dataGridView1.Columns["Status"];
statusColumn.DataPropertyName = "Status";
statusColumn.Items.Add("New");
statusColumn.Items.Add("Hold");
statusColumn.Items.Add("Remove");
// ...
Scenario
I have a DevExpress DataGrid which is bound to a DataSet in C#.
I want to populate each dataset row to contain a string in the first column and a checkbox in the second. My code below doesn't work quite how I want it to, and I'm not sure why.....
The Code
As you can see I've declared a dataset, but when I try and pass in a new checkbox object to the 2nd column it just displays the system name for the checkbox.
DataSet prodTypeDS = new Dataset();
DataTable prodTypeDT = prodTypeDS.Tables.Add();
prodTypeDT.Columns.Add("MurexID", typeof(string));
prodTypeDT.Columns.Add("Haganise",typeof(CheckBox));
//WHY DOES THIS NOT WORK?
//(Displays "System.Windows.Forms.CheckBox, CheckState: 0")
//Instead of a checkbox.
CheckBox c = new CheckBox();
prodTypeDS.Tables[0].Rows.Add("Test",c);
//This doesn't work either....
prodTypeDS.Tables[0].Rows.Add("Test",c.CheckState);
......I hope this is just because it's a DevExpress datagrid....
Why do you use a Checkbox column in your DataSet ?
You should try adding a bool column in your DataSet, when binding the DataSet to the grid, it will automatically use a Checkbox to display the item value.
When you dont have a bool column in your datatable you can also manually/in code set the editor for the column.
Example in code:
Say you add a devex grid column called "fCol".
The value for checked = "YES", unchecked = "NONO";
GridColumn fCol = gridView1.Columns.Add();
RepositoryItemCheckEdit fCheckEdit = new RepositoryItemCheckEdit();
fCheckEdit.ValueChecked = "YES";
fCheckEdit.ValueUnchecked = "NONO";
fCol.ColumnEdit = fCheckEdit;
fCol.FieldName = "Haganise";
Of course you can also do this in the designer.