At the moment I bind my datagridview in a following manner
relations = new CalculationsDataRelations();
bs = new BindingSource();
bs.DataSource = relations.Relations;
DgvRelations.DataSource = bs;
DgvRelations.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
DgvRelations.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
The potential problem I see here is what would happen if I change colums order or insert a column in relations.Relations object.
Is it possible to avoid situations like this and set properties of columns not by index ?
You can access columns by names. This will still be a subject to bugs if you change column names, but probablity is much lower.
you can get the right columns index using the column name of the datasource
Method to Find GridView Column Index by Name
Related
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"
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");
// ...
I have MySQL database and a DataGridView in C# and to fill the DataGridView I do the following:
schoolDataSet schl = new schoolDataSet();
schoolDataSetTableAdapters.studentinfoTableAdapter adptr = new schoolDataSetTableAdapters.studentinfoTableAdapter();
adptr.Fill(schl.studentinfo);
dataGridView1.DataSource = schl.studentinfo.DefaultView;
and undesired columns I make them visible = false from DataGridView properties but I came with a problem if I want to specify what data (rows) to fill in DataGridView such applying a where condition like:
fill data in DataGridView WHERE IsActive = 1 so can I still use the above code with some modifications or I have to write SQL query and fill the DataGridView manually ?
After searching and trying tons of codes I got it as following in simplest code:
In the code above just comment out last line which is dataGridView1.DataSource = schl.studentinfo.DefaultView; or simply replace it with the following
DataView dv = new DataView(schoolDataSet.studentinfo, "IsActive = 'false'", "id", DataViewRowState.CurrentRows);
Which creates a new DataView and filters according to IsActive column with false value, the third parameter id is to sort based-on, and finally you can write another line
dataGridView1.DataSource = dv; that will tell the DataGridView to load data from DataView.
Hope to save someone's time.
Big thanks goes to #Karthik Ganesan
I have a DataGridView whose DataSource is bound to a DataView with a table bound to it. If need to be able to insert columns into the table so I just do this:
DataView.Table.Columns.Add(newColumn);
DataView.Table.Columns[columnCount-1].SetOrdinal(desiredIndex);
Trouble is after doing so the DataGridView reflect the change unless I do something silly like this.
DataView.Table = new DataTable("tempTable");
DataView.Table = orginalTable;
Wondering how to properly get the DataGridView to see the index change and redraw itself?
Update() and Refresh() did not work for me.
So I decided to go the following way:
var temp = dataGridView1.DataSource;
dataGridView1.DataSource = null;
dataGridView1.DataSource = temp;
DataTable dt = new DataTable();
dt.Columns.Add("col1");
dt.Columns.Add("col2");
dt.Columns.Add("col3");
dt.Columns.Add("col4");
dt.Columns.Add("col5");
dataGridView1.DataSource = dt;
dataGridView1.Columns.RemoveAt(3);
dataGridView1.Columns.RemoveAt(2);
dataGridView1.Columns.RemoveAt(0);
In this program, I created a DataTable with 5 columns. This will be the DataSource of the DataGridView. Some columns in the DataTable doesn't need to be seen by the user, but will be used by the program later on.
After the last line, the columns are arranged as : col2, col5, col1, col3, col4. Why does it appear like this? Shouldn't it be removed from the DataGridView? What should I do to make it appear as "col2, col5"?
EDIT: I want to remove some Columns from the DataGridView, yet still be available in the DataTable. Also, it works inside an event (like Button_Click)
EDIT: I still haven't figured out why this is happening. I have no choice but to create another thread (BackgroundWorker) to do this...
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DataTable dt = new DataTable();
int i;
dataGridView1.Invoke((MethodInvoker)delegate
{
dt.Columns.Add("col1");
dt.Columns.Add("col2");
dt.Columns.Add("col3");
dt.Columns.Add("col4");
dt.Columns.Add("col5");
dataGridView1.DataSource = dt;
dataGridView1.Columns.RemoveAt(3);
dataGridView1.Columns.RemoveAt(2);
dataGridView1.Columns.RemoveAt(0);
});
}
As far as I can tell, Haris Hasan was right; that the Form containing the DataGridView should appear at least once. But I'm still confused why...
As far as I know you will have to display DataGridView once before you can remove any column. Try this by displaying DataGridView one time and then delete the columns and see what happens
Instead of removing the columns you could try setting their visibility...
dataGridView1.DataSource = dt;
dataGridView1.Columns[3].Visible = false;
dataGridView1.Columns[2].Visible = false;
dataGridView1.Columns[0].Visible = false;
You can use DisplayIndex property of the DataGridView to order the columns. In order to hide a column you can set false to the Visible property of a particular column.
dataGridView1.Columns["ColumnTobeHided"].Visible = false;
If you don't want columns in the grid for all of the columns in the table, set datagridview.AutoGenerateColumns to false before binding the datatable to the datasource. Then create and bind the datagridview columns you actually want to have.
AutoGenerateColumns defaults to true, and yet it very seldom gives us what we really want. Take the time to build your datagridview columns exactly as you want and don't trust the default processing.