I have been working on asp.net/C# project. I could bind the DataTable to gridview. But i have a situation where i don't want to bind all the records in DataTable. is there any method to bind only few records to gridview? any Alternatives to GridView.DataBind()?
Thank you
try this,
using datatable select query you can achieve this,
for example,
DataTable dt=yourdata;
DataRow[] dr=dt.Select("columnname='Maths'");
foreach (DataRow row in dr) {
dt.ImportRow(row);
}
GridView1.DataSource=dt;
GridView1.DataBind();
where Maths = your search criteria.
You can add the rows manually, i.e. without using a data source.
var newRowIndex = dataGridView1.Rows.Add(firstValue, secondValue, thirdValue);
You might use it like this:
foreach (System.Data.DataRow row in myDataTable.Rows)
{
if(meets my criteria...)
{
dataGridView1.Rows.Add(row["Column1"], row["Column2"], row["Column3"]);
}
}
In fact, this may be a better solution as it allows you to sort columns easily in the UI whereas binding to a data source does not allow that.
Use DataView for the DataTable, So that you can able to filter records and assign the dataview to Grid.
for example:
DataView dv = new DataView(DataTable, "Column1=Value", "Column2", DataViewRowState.CurrentRows);
Related
I am creating a WPF application. There is a DataGrid displaying my items and search bar to filter the data. As you know we can't have specific rows from a Dataable to be referenced from another datatable. So the way I'm filtering right now is cloning my original database and adding the rows which matches search bar text to the cloned datatable. After that setting the datagrid's ItemsSource to the cloned datatable to show the filtered rows.
Now the problem is that when I edit my datagrid with filtered rows then obviously that cloned datatable is being modified not the original datatable. So how can I make those changes in the original datatable as well ?
I tried referencing rows from original datatable but that's no possible as one DataRow in memory can have only one container, the original datatable in this case.
EDIT
The answer was simple instead of using 2 DataTable use a DataView which is designed for this very purpose. See the modified code below.
My filter logic:
var filteredTable = dt.Clone();
foreach( DataRow row in dt.Rows)
{
if(row[FilterCategory].ToString().StartsWith(txtb_search.Text))
{
filteredTable.Rows.Add(row.ItemArray);
}
}
ItemsGrid.ItemsSource = filteredTable.DefaultView;
Here is how to do filtering the correct way using DataView. The filter string can have many forms depending on the requirement. sortColumn is filterColumn right now but can be any column to base sort on. Here is a quick tutorial to all this: http://www.csharp-examples.net/dataview-rowfilter/
string filterColumn = dt.Columns[columnIndex].ToString();
string filter = filterColumn + " LIKE '" + txtb_search.Text + "*'";
DataView dv = new DataView(dt, filter, sortColumn , DataViewRowState.CurrentRows);
ItemsGrid.ItemsSource = dv;
I have a datatable filled with a report from a web service. I am now trying to display the datatable in an datagridview. This is the code I use to build the datatable:
// Create DataTabe to handle the output
DataTable dt = new DataTable();
dt.Clear();
dt.Columns.Add("EmployeeFirstName");
dt.Columns.Add("EmployeeLastName");
dt.Columns.Add("DepartmentName");
dt.Columns.Add("DepartmentCode");
dt.Columns.Add("LocationName");
dt.Columns.Add("DivisionCode");
dt.Columns.Add("EarningName");
dt.Columns.Add("OTHours");
dt.Columns.Add("WorkDate")
Fill the new datatable:
foreach (ReportRow row in report.Rows)
{
dt.Rows.Add(string.Join(",", row.ColumnValues));
}
Then I try to bind the data in the datatable to the dataGridview:
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = dt;
dataGridView1.Refresh();
When I run the application it only displays the data from the first column in the datatable. Do I need a loop of sorts to work through the columns or am I just missing a step?
Yes that's cause you are adding only one value to your dt when you say dt.Rows.Add(string.Join(",", row.ColumnValues));. You should be doing something like below (assuming that ReportRow also has the columns with same names like "EmployeeFirstName" else change the names accordingly)
foreach (ReportRow row in report.Rows)
{
DataRow dr = dt.NewRow();
dr["EmployeeFirstName"] = row["EmployeeFirstName"];
dr["EmployeeLastName"] = row["EmployeeLastName"];
dr["DepartmentName"] = row["DepartmentName"];
//rest of the columns fill
//once all columns filled
dt.Rows.Add(dr);
}
dt.Rows.Add(string.Join(",", row.ColumnValues)); -> You can either add a single DataRow item or a array of objects.
From your call, you chose the later, you are adding a array of objects, except you are adding ONE SINGLE object.
string.Join(",", row.ColumnValues) is one object.
Well after sleeping I have found the issue with dropping it into an sql table... I didn't take into account that the export to a CSV and the addition of the " , " would affect the export to sql. Here is the modification of the lines of code that was the issue:
foreach (ReportRow row in report.Rows)
{
dt.Rows.Add(row.ColumnValues);
}
Thank you all for your responses!
I want to use the user-selected rows from one DataGridView as the DataSource for a second DataGridView. Note both DataGridViews will have identical columns.
Obviously I can iterate over the selected rows, obtain the key values, and re-query the database for a List to use as the DataSource of the 2nd grid, but that seems lame.
Surely there is an elegant way of simply re-using the SelectedRows collection as a DataSource?
You cannot directly set collection of DataRow as datasource, you can read more details from MSDN
How about doing (bit) traditional way?
var dt = ((DataTable)dataGrid1.DataSource).Clone();
foreach (DataGridViewRow row in dataGrid1.SelectedRows)
{
dt.ImportRow(((DataTable)dataGrid1.DataSource).Rows[row.Index]);
}
dt.AcceptChanges();
dataGrid2.DataSource = dt;
Another way to do this using CopyToDataTable method.
DataTable dtable2;
DataRow[] rowArray = dataGridView1.SelectedRows;
If !(rowArray.Length == 0 )
{
dTable2 = rowArray.CopyToDataTable();
}
dataGrodView2.DataSource = dTable2;
Thanks for your replies. Seems there isn't a very simple way.
I did it this way:
MyDatGridView.SelectedRows.Cast<DataGridViewRow>().Select(dgvr => (int)dgvr.Cells[0].Value).ToList());
Then I tried to use the resulting List with a .Contains in a .Where clause.
How to sort datatable obtained by GridView according to some column.
I am trying to do something like this but it is not working.
protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
{
if (sender.GetType() != typeof(GridView))
return;
DataTable dt = (DataTable)((GridView)sender).DataSource;
DataTable dtClone = dt.Clone();
dt.AsEnumerable().OrderBy(row => row.Field <string>(e.SortExpression));
((GridView)sender).Source(dtClone);
}
You can either re-bind the gridview to the sorted datatable, or you can apply the sort expression to the gridview itself rather than the underlying bound table.
This is a pretty good summary with links to examples:
http://msdn.microsoft.com/en-us/library/hwf94875.aspx
Add the attributes OnSorting="gridView_Sorting" AllowSorting="true" in Gridview
and SortExpression="ColumnName" in the column
and implement OnSorting Event.
check the links
Sorting the GridView's Data
How to sort the data in grid view?
How to sort data into GridView
Sorting Data in a GridView
How to sort GridView?
I've done something like this in the past to sort a DataTable:
DataTable dt = new DataTable(); // your data table
dt.DefaultView.Sort = "your_field" + "sort_direction";
DataView dv = new DataView(dt);
dv.Sort = ("your_field" + "sort_direction");
yourGridView.DataSource = dv;
When sorting, make sure to cast your table to a DataView. You'll save yourself a lot of time over manually implementing sorting methods.
I am using C# and .NET 3.5 and have a GridView that I am setting the dataSource programatically in the code-behind page. I have data in a DataTable and then depending on a column value (isValid boolean) of each Row, I create a new row using DataRowView.AddNew() method into 1 of 2 DataViews - dvValid or dvInvalid. I am NOT creating a new DataTable.NewRow to add to the DataView Table. Then I bind the GridView to the appropriate dataView.
There is a problem when I am sorting the GridView. I am having a problem with 1 row not being sorted correctly, all other rows are sorted fine. I debugged my code and found that the DataView.Count is 1 more than the DataView.Table.Rows.Count even though I am calling DataView.Table.AcceptChanges() method. This is strange since the dataTable should have all committed rows and therefore the counts should be the same.
So why are the 2 counts different? A DataView is a subset of the DataTable so should it not have equal or less rows than the DataTable.
When I populate the DataView, should I first create the DataTables rather than creating the DataView directly? Right now, I am directly creating a DataRowView without a dDataTableRow, is this the correct approach?
Thanks for your help.
Code snippet : C#
...
//get the data as DataTable
members = GetMemberDataTable ();
//create views from a new DataTable with no rows
dvValidMembers = new DataView (CreateMembersDT("ValidMembers"));
dvInValidMembers = new DataView (CreateMembersDT("InvalidMembers"));
//iterate thru each row and put into appropriate DataView
foreach (DataRow memberRow in members.Rows)
{
if ((bool)memberRow["isValid"])
//Add to valid members Dview
member = dvValidMembers.AddNew();
else
//add to InValid members Dview
member = dvInvalidMembers.AddNew();
member["memberID"] = memberRow["memID"];
} //foreach
dvInvalidMembers.Table.AcceptChanges();
dvValidMembers.Table.AcceptChanges();
}
private System.Data.DataTable CreateMembersDT ( string tableName)
{
System.Data.DataTable dtMembers = new System.Data.DataTable(tableName);
dtMembers.Columns.Add(new DataColumn("memID", typeof(int)));
return dtMembers;
}
That 1 row that isn't sorting right, could that be the last row?
I think you are missing a DataView.EndEdit():
foreach (DataRow memberRow in members.Rows)
{
DataView dv;
if (...)
//Add to valid members Dview
dv = dvValidMembers;
else
dv = dvInvalidMembers;
member = dv.Addnew();
member["memberID"] = memberRow["memID"];
dv.EndEdit();
}
But I would also like to note that you could probably use 2 Views with a Filter on isValid and then you would only need to point them to the original members table.