问题
In my .aspx page, I have an <asp:GridView runat="server" ID="CustomerGridView">
control which I bind like this:
public partial class InsertCustomer : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewCustomer();
}
}
private void ViewCustomer()
{
var manager = new DomainManager();
var result = manager.FindAll(new Customer());
this.CustomerGridView.DataSource = result;
this.CustomerGridView.DataBind();
}
}
Here is the DomainManager
class:
public class DomainManager
{
readonly StringBuilder _queryBuilder = new StringBuilder();
private Type _entityType;
readonly SQLHelper _sqlHelper = new SQLHelper();
public IEnumerable FindAll<T>(T entity)
{
_entityType = entity.GetType();
var query = string.Format("select * from {0}", _entityType.Name);
var dt = _sqlHelper.FillDataTable(query);
return dt.AsEnumerable();
}
}
The problem is that my grid is not being bound correctly. Why not?
回答1:
Try changing
return dt.AsEnumerable();
to
return dt.DefaultView;
Explanation: By default, a GridView
binds to actual properties of an object. For example, if the data source is a List<Customer>
, then you can bind to the Name
property of each Customer
. But when the data source is a DataTable
of customers, then each customer is represented by a DataRow
, and a DataRow
does not have a Name
property that the GridView
can bind to.
To support dynamic properties, an object must implement the ICustomTypeDescriptor
interface. This interface is implemented by DataRowView
but not DataRow
. By changing the code to return dt.DefaultView
(which is a DataView
), you provide the GridView
with a collection of DataRowView
objects that it can bind to.
Now you might be wondering why
this.CustomerGridView.DataSource = dt;
works, but
this.CustomerGridView.DataSource = dt.AsEnumerable();
doesn't.
The reason is that DataTable
implements the IListSource
interface, which tells the GridView
"don't use me as the data source, use my DefaultView
instead." But AsEnumerable()
returns a wrapper object that doesn't implement IListSource
, so the GridView
doesn't know how to get to the DefaultView
.
来源:https://stackoverflow.com/questions/9432688/why-does-calling-asenumerable-on-a-datatable-prevent-a-gridview-from-binding-t