Why DataColumn.Caption doesn't work? - c#

I am trying to create a DataTable and bind it to a DataGridView. It works, but I can't set columns headers via the Caption property. It displays headers using the ColumnName ("City") instead. MSDN says that
"You can use the Caption property to display a descriptive or friendly
name for a DataColumn."
Here is my code:
DataColumn dc = new DataColumn("City", typeof(string));
dc.Caption = "Город";
DataTable dt = new DataTable();
dt.Columns.Add(dc);
DataRow row = dt.NewRow();
row["City"] = "Moscow";
dt.Rows.Add(row);
datagridview.DataSource = dt;

Well, MSDN is right. That is what the Caption property is for. However, that doesn't mean that control makers have to use the caption property. In this case, Microsoft didn't do that (although they really should have). You can modify your code to this though:
///snip
dataGridView1.DataSource = dt;
foreach (DataGridViewColumn col in dataGridView1.Columns) {
col.HeaderText = dt.Columns[col.HeaderText].Caption;
}

I think when you bind to a DataTable, the DataGridView does not use the Caption property. It only works when you bind to a DataSet.
You can modify the column headers manually like this:
dataGridView.Columns[i].HeaderText = dt.Columns[i].Caption;

You should try this:
datagridView.Columns[0].HeaderText = "Title Goes Here.";
You may do this for the number of columns you have added. Only the index will change.

in vb.net code :
Dim dt As New DataTable
dt.Columns.Add("col1").Caption = "Your Header Text"
'and add more columns with .caption
GridView1.DataSource = dt
For Each col As DataColumn In dt.Columns
GridView1.Columns(col.ColumnName).HeaderText = col.Caption
Next

#aquinas, this works for me
foreach (DataGridViewColumn col in dataGridView1.Columns) {
col.HeaderText = dt.Columns[col.Name].Caption;
}

foreach (DataTable dataTable in dataSet.Tables)
{
form1.Controls.Add(new LiteralControl(String.Format("<h1>{0}</h1>", dataTable.TableName)));
GridView grid = new GridView();
grid.AllowPaging = false;
grid.AutoGenerateColumns = false;
foreach (DataColumn col in dataTable.Columns)
{
grid.Columns.Add(new BoundField { DataField = col.ColumnName, HeaderText = col.Caption });
}
grid.DataSource = dataTable;
grid.DataBind();
form1.Controls.Add(grid);
}

Related

How do i add more cells to a column of datagridview?

Now i have one cell i added it in the designer but if i want to add more cells in my code ?
I tried in the constructor to do:
DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
dataGridView1.Rows.Add(row);
But getting exception on:
row.Cells[1].Value = 50.2;
Index was out of range. Must be non-negative and less than the size of the collection
Yes you should get an exception. Look at your code below. With row.Cells[1] you are actually referring to 2nd column in your gridview which apparently doesn't exists and so the end result.
row.Cells[1].Value = 50.2;
If you want to have another column to your grid then either add that using your designer surface (OR) create a DataTable with required columns and set that to DataSource of your gridview.
How to create a DataTable and attach it to GridView?
Search Google
EDIT:
In case you are still struggling understanding my comment then this is what I meant to say (sample code)
public Form1()
{
InitializeComponent();
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("Message Subject");
dt.Columns.Add(dc);
DataRow dr = dt.NewRow();
dr[dc] = "test";
DataRow dr1 = dt.NewRow();
dr1[dc] = "test123";
dt.Rows.Add(dr);
dt.Rows.Add(dr1);
this.dataGridView1.DataSource = dt;
}

Disable sorting feature on columns?

I am generating a DataTable in C# and I need to disable sorting the columns via code. The code is something like:
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add("File_Name");
dt.Columns.Add("Create_Date");
dt.Columns.Add("Status");
dr = dt.NewRow();
dataGridView1.DataSource = dt;
How can this be accomplished? I did check for things like dt.SortMode = <something disabled> but so far didn't find any SortOrder on the data element.
Here's a more robust example. I tested this in Windows forms application (.NET 4.5, VS 2012)
DataTable dt = new DataTable();
dt.Columns.Add("File_Name");
dt.Columns.Add("Create_Date");
dt.Columns.Add("Status");
DataRow dr = dt.NewRow();
dr["File_Name"] = "abc.txt";
dr["Create_Date"] = DateTime.Now;
dr["Status"] = "Pending";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["File_Name"] = "xyz.bmp";
dr["Create_Date"] = DateTime.Now;
dr["Status"] = "Complete";
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
col.SortMode = DataGridViewColumnSortMode.NotSortable;
}
Hope this helps.
:) David
"AllowUserToOrderColumns" has nothing to do with sorting data, it determines whether or not the user is allowed to rearrange the columns in the grid. You can disable sorting certain grid columns by setting the respective columns' SortMode as such
myDataGridViewTextBoxColumn.SortMode = DataGridViewColumnSortMode.NotSortable

How to add a new row to datagridview programmatically

if add row to DataTable
DataRow row = datatable1.NewRow();
row["column2"]="column2";
row["column6"]="column6";
datatable1.Rows.Add(row);
How about DataGridView??
You can do:
DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
yourDataGridView.Rows.Add(row);
or:
DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells["Column2"].Value = "XYZ";
row.Cells["Column6"].Value = 50.2;
yourDataGridView.Rows.Add(row);
Another way:
this.dataGridView1.Rows.Add("five", "six", "seven","eight");
this.dataGridView1.Rows.Insert(0, "one", "two", "three", "four");
From: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rows.aspx
Like this:
var index = dgv.Rows.Add();
dgv.Rows[index].Cells["Column1"].Value = "Column1";
dgv.Rows[index].Cells["Column2"].Value = 5.6;
//....
Lets say you have a datagridview that is not bound to a dataset and you want to programmatically populate new rows...
Here's how you do it.
// Create a new row first as it will include the columns you've created at design-time.
int rowId = dataGridView1.Rows.Add();
// Grab the new row!
DataGridViewRow row = dataGridView1.Rows[rowId];
// Add the data
row.Cells["Column1"].Value = "Value1";
row.Cells["Column2"].Value = "Value2";
// And that's it! Quick and painless... :o)
Like this:
dataGridView1.Columns[0].Name = "column2";
dataGridView1.Columns[1].Name = "column6";
string[] row1 = new string[] { "column2 value", "column6 value" };
dataGridView1.Rows.Add(row1);
Or you need to set there values individually use the propery .Rows(), like this:
dataGridView1.Rows[1].Cells[0].Value = "cell value";
Adding a new row in a DGV with no rows with Add() raises SelectionChanged event before you can insert any data (or bind an object in Tag property).
Create a clone row from RowTemplate is safer imho:
//assuming that you created columns (via code or designer) in myDGV
DataGridViewRow row = (DataGridViewRow) myDGV.RowTemplate.Clone();
row.CreateCells(myDGV, "cell1", "cell2", "cell3");
myDGV.Rows.Add(row);
This is how I add a row if the dgrview is empty: (myDataGridView has two columns in my example)
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(myDataGridView);
row.Cells[0].Value = "some value";
row.Cells[1].Value = "next columns value";
myDataGridView.Rows.Add(row);
According to docs: "CreateCells() clears the existing cells and sets their template according to the supplied DataGridView template".
If the grid is bound against a DataSet / table its better to use a BindingSource like
var bindingSource = new BindingSource();
bindingSource.DataSource = dataTable;
grid.DataSource = bindingSource;
//Add data to dataTable and then call
bindingSource.ResetBindings(false)
here is another way to do such
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.ColumnCount = 3;
dataGridView1.Columns[0].Name = "Name";
dataGridView1.Columns[1].Name = "Age";
dataGridView1.Columns[2].Name = "City";
dataGridView1.Rows.Add("kathir", "25", "salem");
dataGridView1.Rows.Add("vino", "24", "attur");
dataGridView1.Rows.Add("maruthi", "26", "dharmapuri");
dataGridView1.Rows.Add("arun", "27", "chennai");
}
If you need to manipulate anything aside from the Cell Value string such as adding a Tag, try this:
DataGridViewRow newRow = (DataGridViewRow)mappingDataGridView.RowTemplate.Clone();
newRow.CreateCells(mappingDataGridView);
newRow.Cells[0].Value = mapping.Key;
newRow.Cells[1].Value = ((BusinessObject)mapping.Value).Name;
newRow.Cells[1].Tag = mapping.Value;
mappingDataGridView.Rows.Add(newRow);
If you are binding a List
List<Student> student = new List<Student>();
dataGridView1.DataSource = student.ToList();
student .Add(new Student());
//Reset the Datasource
dataGridView1.DataSource = null;
dataGridView1.DataSource = student;
If you are binding DataTable
DataTable table = new DataTable();
DataRow newRow = table.NewRow();
// Add the row to the rows collection.
table.Rows.Add(newRow);
yourDGV.Rows.Add(column1,column2...columnx); //add a row to a dataGridview
yourDGV.Rows[rowindex].Cells[Cell/Columnindex].value = yourvalue; //edit the value
you can also create a new row and then add it to the DataGridView like this:
DataGridViewRow row = new DataGridViewRow();
row.Cells[Cell/Columnindex].Value = yourvalue;
yourDGV.Rows.Add(row);
If anyone wanted to Add DataTable as a source of gridview then--
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("column1"));
dt.Columns.Add(new DataColumn("column2"));
DataRow dr = dt.NewRow();
dr[0] = "column1 Value";
dr[1] = "column2 Value";
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
An example of copy row from dataGridView and added a new row in The same dataGridView:
DataTable Dt = new DataTable();
Dt.Columns.Add("Column1");
Dt.Columns.Add("Column2");
DataRow dr = Dt.NewRow();
DataGridViewRow dgvR = (DataGridViewRow)dataGridView1.CurrentRow;
dr[0] = dgvR.Cells[0].Value;
dr[1] = dgvR.Cells[1].Value;
Dt.Rows.Add(dR);
dataGridView1.DataSource = Dt;
Consider a Windows Application and using Button Click Event put this code in it.
dataGridView1.Rows
.Add(new object[] { textBox1.Text, textBox2.Text, textBox3.Text });
//Add a list of BBDD
var item = myEntities.getList().ToList();
//Insert a new object of type in a position of the list
item.Insert(0,(new Model.getList_Result { id = 0, name = "Coca Cola" }));
//List assigned to DataGridView
dgList.DataSource = item;
//header
dataGridView1.RowCount = 50;
dataGridView1.Rows[0].HeaderCell.Value = "Product_ID0";
//add row by cell
dataGridView1.Rows[1].Cells[0].Value = "cell value";
If you´ve already defined a DataSource, You can get the DataGridView´s DataSource and cast it as a Datatable.
Then add a new DataRow and set the Fields Values.
Add the new row to the DataTable and Accept the changes.
In C# it would be something like this..
DataTable dataTable = (DataTable)dataGridView.DataSource;
DataRow drToAdd = dataTable.NewRow();
drToAdd["Field1"] = "Value1";
drToAdd["Field2"] = "Value2";
dataTable.Rows.Add(drToAdd);
dataTable.AcceptChanges();
I think the cleanest way to do is invoking the DataGridView and using a lambda expression. Simple one liner while also keeping the code thread safe:
MyDataGridView.Invoke((MethodInvoker)(() => MyDataGridView.Rows.Add(param1, param2, paramX)));
I have found this useful more than once when the DataGrid is bound to a table.
DataTable dt = (DataTable)dgvData.DataSource;
DataRow row = dt.NewRow();
foreach (var something in something)
{
row["ColumnName"] = something ;
}
dt.Rows.Add(row);
dgvData.DataSource = dt;
string[] splited = t.Split('>');
int index = dgv_customers.Rows.Add(new DataGridViewRow());
dgv_customers.Rows[index].Cells["cust_id"].Value=splited.WhichIsType("id;");
But be aware, WhichIsType is the extension method I created.

How create DataGridViewComboBoxColumn from simple DataTable

I create user control, editing, showing range DataGridView.
My user control takes DataTable
public static DataTable CreateDataTable()
{
var myDataTable = new DataTable();
DataColumn myDataColumn;
myDataColumn = new DataColumn
{
DataType = Type.GetType("System.String"),
ColumnName = "id",
ReadOnly = true
};
myDataTable.Columns.Add(myDataColumn);
myDataColumn = new DataColumn
{
DataType = Type.GetType("System.String"),
ColumnName = "citys"
};
myDataTable.Columns.Add(myDataColumn);
return myDataTable;
}
I set myDataTables to DataSource and all worked.
but I need to create column citys DataGridViewComboBoxColumn.
How to do this?
try this
DataGridViewComboBoxColumn oCol = new DataGridViewComboBoxColumn();
oCol.Name = "cities";
oCol.DataSource = //your DataSource
myDataGridView.Columns.Add(oCol);
Hope it helped !
Try this way:
DataTable table = CreateDataTable();
foreach (DataColumn column in table.Columns)
{
dataGridView1.Columns.Add(column.ColumnName, column.ColumnName);
}
//there is you code too here.

Best way add a new column with sequential numbering in an existing data table

I have a non empty datatable . What is the best way to add another column to it that has sequential numbering starting from 1.
I tried the following code. But did not work.
DataColumn dc = new DataColumn("Col1");
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
dc.DataType = typeof(Int32);
dt.Columns.Add(dc);
Will setting any expression help in this scenario ?
Thanks in Advance
I think you could achieve that by using a 2nd "helper" data table that would contain just an auto-increment field and then you populate/merge it with the existing data, something like this:
DataTable dtIncremented = new DataTable(dt.TableName);
DataColumn dc = new DataColumn("Col1");
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
dc.DataType = typeof(Int32);
dtIncremented.Columns.Add(dc);
dtIncremented.BeginLoadData();
DataTableReader dtReader = new DataTableReader(dt);
dtIncremented.Load(dtReader);
dtIncremented.EndLoadData();
And then you would just return dtIncremented table instead of the original dt. Not an elegant solution but should work.
below code worked for me
Code is Edited
// Added temp rows so that this solution can mimic actual requirement
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("Col");
dt.Columns.Add(dc1);
for(int i=0;i<10;i++)
{
DataRow dr = dt.NewRow();
dr["Col"] = i.ToString();
dt.Rows.Add(dr);
}
// Added new column with Autoincrement,
DataColumn dc = new DataColumn("Col1");
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.DataType = typeof(Int32);
// Handeled CollectionChanged event
dt.Columns.CollectionChanged += new CollectionChangeEventHandler(Columns_CollectionChanged);
dt.Columns.Add(dc);
// After column added demostratation
DataRow dr1 = dt.NewRow();
dt.Rows.Add(dr1);
void Columns_CollectionChanged(object sender, CollectionChangeEventArgs e)
{
DataColumn dc = (e.Element as DataColumn);
if (dc != null && dc.AutoIncrement)
{
long i = dc.AutoIncrementSeed;
foreach (DataRow drow in dc.Table.Rows)
{
drow[dc] = i;
i++;
}
}
}
You'll have to build a whole new datatable for this and manually deep-copy each row one by one from the old table to the new. Sorry.

Categories