AngelicCore
AngelicCore

Reputation: 1453

Unable to set datasource of datagridview from List

I have a datagridview that's getting its data from Access via OleDbDataReader.

The problem is as follows Reading data into Data table then setting datasource = dt => works

dt.Load(dr);

taking the dt and applying Linq to it => empty GridView

GVMultiple.DataSource = (from myRow in dt.AsEnumerable()
                         where myRow.Field<string>("State") == "Succeeded"
                         select myRow)

making the Linq.ToList() => shows columns with names "RowError","RowState","Table" and "hasErrors" which aren't my columns

GVMultiple.DataSource = (from myRow in dt.AsEnumerable()
                         where myRow.Field<string>("State") == "Succeeded"
                         select myRow).ToList()

Reading data into Object of a custom List then setting datasource = List => empty GridView

while (dr.Read())
{
    UserList.Add(new UserInfo()
    {
        ID = (int)dr["ID"],
        UserName = (string)dr["User Name"]
    });
}

GVMultiple.DataSource = UserList

Can someone tell me what is going on?

Upvotes: 0

Views: 1483

Answers (3)

Ashraf Sada
Ashraf Sada

Reputation: 4905

The reason for that is that the data grid view is not able to recognize the collection of new data as accepted format for display.

When using Linq queries to filter the data and re display it in data grid view you must always return the query result to any data source as data view.

DataView constructs an index, which significantly increases the performance of operations that can use the index, such as filtering and sorting. The index for a DataView is built both when the DataView is created and when any of the sorting or filtering information is modified. Creating a DataView and then setting the sorting or filtering information later causes the index to be built at least twice: once when the DataView is created, and again when any of the sort or filter properties are modified.

For example:

DataTable dt = empData.loadEmployee();
BindingSource bs = new BindingSource();
bs.DataSource = dt.AsEnumerable()
    .Where(c => c.Field<string>("First Name").ToLower()
    .Contains(txtSearch.Text.ToLower())).AsDataView();

dgvEmpManag.DataSource = bs;

In the example I am looking for employee with first name like the search term in the text box txtSearch when found the data grid view will display filtered results of my search AsDataView().

Upvotes: 0

tim
tim

Reputation: 536

GVMultiple.DataSource = (from myRow in dt.AsEnumerable() where myRow.Field("State") == "Succeeded" select myRow)

making the Linq.ToList() => shows columns with names "RowError","RowState","Table" and "hasErrors" which aren't my columns

RowError","RowState","Table" and "hasErrors" are properties of the DataRow - which is what is in the list you created.

Take a look into the .CopyToDataTable() extension method. http://msdn.microsoft.com/en-us/library/bb396189.aspx

    GVMultiple.DataSource = (from myRow in dt.AsEnumerable()
                     where myRow.Field<string>("State") == "Succeeded"
                     select myRow).CopyToDataTable();

Upvotes: 1

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

In order to make DataBinding work you've to use Properties. Fields doesn't support DataBinding.

Modify your class as below to make it work.

class UserInfo 
{ 
    public int ID {get;set;}  //convert fields to property
    public string UserName{get;set;}
} 

Upvotes: 1

Related Questions