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
Related
I have DataGridView that i am adding items via DataTable
This items read from XML file and inside this XML file,
those items not sorted and i want to sort is before add to my DataGridView
private void UpdateDataGdirView(List<Vendor> list)
{
DataTable dt = new DataTable();
dt.Columns.Add("Column1", System.Type.GetType("System.Boolean"));
dt.Columns.Add("Column2", typeof(string));
dt.Columns.Add("Column3", System.Type.GetType("System.Boolean"));
dt.Columns.Add("Column4", System.Type.GetType("System.Boolean"));
dt.Columns.Add("Column5", System.Type.GetType("System.Boolean"));
dt.Columns.Add("Column6", System.Type.GetType("System.Boolean"));
DataRow dr;
foreach (Vendor vendor in list)
{
dr = dt.NewRow();
dr["Column1"] = vendor.IsVendorChecked;
dr["Column2"] = vendor.Number;
dr["Column3"] = vendor.Name;
dr["Column4"] = vendor.Size;
dr["Column5"] = vendor.Path;
dr["Column6"] = vendor.Path2;
dt.Rows.Add(dr);
}
dataGridView1.AllowUserToAddRows = false;
dataGridView1.AllowUserToDeleteRows = false;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.Invoke((MethodInvoker)delegate { dataGridView1.DataSource = dt; });
}
you can use
dt.defaultview.sort="columnname asc/desc"
and then bind the datatable to its destination.
I think you should use DataView for this. Like :
DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
orderby order.Field<decimal>("TotalDue")
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
Follow this link : Query on DataView
OR
You can use like :
DataTable orders = dataSet.Tables["SalesOrderHeader"];
DataView dv = new DataView(orders);
dv.Sort = "TotalDue";
dataGridView1.DataSource = dv;
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);
}
I have a windows application in which I am going to delete a datarow from a datatable.
But I got an exception.
The given DataRow is not in the current DataRowCollection.
The code:
DataTable dt = new DataTable();
DataRowView currentDataRowView = (DataRowView)DataGridView1.CurrentRow.DataBoundItem;
DataRow row = currentDataRowView.Row;
dt.Rows.Remove(row); // exception here.
DataGridView1.DataSource = dt;
The datatable dt's information as the image shown.
I think that I already have casted datarowview to datarow.
EDIT:
dt was created from another DataGridView.
foreach (DataGridViewRow row in DatGridView2.Rows)
{
DataGridViewCheckBoxCell check = row.Cells[0] as DataGridViewCheckBoxCell;
if (check.Value != null)
{
if ((bool)check.Value)
{
//this row has a checkBox set to true (tick is added)
//add this row to dataTable ...
DataRow myRow = (row.DataBoundItem as DataRowView).Row;
DataRow dr = dt.NewRow();
dr[0] = myRow[0];
dr[1] = myRow[1];
dr[2] = myRow[2];
dr[3] = myRow[3];
if (!dt.Rows.Contains(dr[0]))
{
dt.Rows.Add(dr);
}
}
}
I don't think you can reference a different DataTable than the one where CurrentRow.DataBoundItem is coming from.
Your dt DataTable is being constructed from DataGridView2 but CurrentRow.DataBoundItem is coming from DataGridView1.
You will have to find the matching row in DataGridView1 yourself before you can delete it.
I have tried your code, and it's working with no problem:
DataTable dt = (DataTable)dataGridView1.DataSource;
DataRowView currentDataRowView = (DataRowView)dataGridView1.Rows[0].DataBoundItem;
DataRow row = currentDataRowView.Row;
dt.Rows.Remove(row);
dataGridView1.DataSource = dt;
So as i have wrote above, the error "The given DataRow is not in the current DataRowCollection" means that your trying to delete a row that is not in the DataTable "dt".
Q:
I want to rename my data table column names .
I tried this :
dt.Columns[8].ColumnName = "regnum";
dt.AcceptChanges();
but my data is lost after that !!
dt.Columns[8].ColumnName = "regnum";
This just binds your Columns[8] to the non-existing "regnum" column in the Db.
If you want to rename the actuals Db column, execute an SQL script.
But my guess is you actually want to change the Caption:
dt.Columns[8].Caption = "regnum";
Following is the example:
DataTable Dt = new DataTable();
DataColumn Dc = new DataColumn("Name");
DataColumn Dc1 = new DataColumn("ID");
Dt.Columns.Add(Dc);
Dt.Columns.Add(Dc1);
DataRow dr = Dt.NewRow();
dr["name"] = "1";
dr["ID"] = "111";
Dt.Rows.Add(dr);
dr = Dt.NewRow();
dr["name"] = "2";
dr["ID"] = "11112";
Dt.Rows.Add(dr);
Dt.Columns[0].ColumnName = "ddsxsd";
Dt.AcceptChanges();
I did not find any data loss!!!!!!!! Because it will merely change the column name.
EDIT
You can also bring your desired column names from your Stored Procedures.
Try this:
dataTable.Columns["ExistingColumnName"].ColumnName = "regnum";
Also may this code serve someone!
I have a realize that this is the easiest way just like #Henk said:
using (SqlDataAdapter da = new SqlDataAdapter())
{
DataTable dt = new DataTable();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
da.SelectCommand = cmd;
da.Fill(dt);
dt.Columns[0].ColumnName = "Item NO";
dt.Columns[1].ColumnName = "LocalCode";
dt.Columns[2].ColumnName = "Currency";
dt.Columns[3].ColumnName = "Menu Flag";
dt.Columns[4].ColumnName = "Item Class";
dt.Columns[4].ColumnName = "Dress Sort";
return dt;
}
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.