I created custom datatype classes that format the data the way I need it. The data I retrieve from the database comes as .NET base types, so I need to loop through the DataTable, convert each item into it's custom type, and put the converted item into a new table. I also copy the column names from the old table to the new one. The problem is, when I bind a GridView to my new table, it throws an exception:
我创建了自定义数据类型,以我需要的方式格式化数据。我从数据库中检索的数据是.NET基类型,因此我需要遍历DataTable,将每个项目转换为自定义类型,并将转换后的项目放入新表中。我还将旧表中的列名复制到新表中。问题是,当我将GridView绑定到我的新表时,它会抛出异常:
HttpException:
The data source for GridView with id 'TestGrid' did not have any properties
or attributes from which to generate columns. Ensure that your data source
has content.
Stack Trace:
at System.Web.UI.WebControls.GridView.CreateAutoGeneratedColumns(PagedDataSource dataSource)
at System.Web.UI.WebControls.GridView.CreateColumns(PagedDataSource dataSource, Boolean useDataSource)
at System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
at System.Web.UI.WebControls.CompositeDataBoundControl.PerformDataBinding(IEnumerable data)
at System.Web.UI.WebControls.GridView.PerformDataBinding(IEnumerable data)
at System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(IEnumerable data)
at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
at System.Web.UI.WebControls.GridView.DataBind()
What do I need to add to my DataTable to get autogeneratecolumns to work?
我需要添加到DataTable以使autogeneratecolumns工作?
Edit: Here is the code for the DataTable:
编辑:这是DataTable的代码:
// Populate first DataTable with data from database.
adapter = new DataAdapter("SELECT status, date_ordered, date_due FROM import_table", OpenConnection);
DataTable originalTable = new DataTable();
adapter.Fill(originalTable)
// Second DataTable for converted table data.
DataTable convertedTable = new DataTable();
// The list of custom datatypes to convert to.
Type[] newTypes = {typeof(TrackingStatus), typeof(Date), typeof(Date)};
// Set the ColumnName and DataType on each column of the new table.
for(int i = 0; i < originalTable.Columns.Count; i++)
{
convertedTable.Columns.Add();
convertedTable.Columns[i].ColumnName = originalTable.Columns[i].ColumnName;
if(newTypes.Length > i)
convertedTable.Columns[i].DataType = newTypes[i];
}
// Convert each item from the old table and add it to the new table.
foreach(DataRow oldRow in originalTable.Rows)
{
DataRow newRow = convertedTable.NewRow();
for(int i = 0; i < convertedTable.Columns.Count; i++)
{
if(newTypes.Length <= i)
newRow[i] = oldRow[i];
else if(newTypes[i] == typeof(Date))
newRow[i] = Date.FromObject(oldRow[i]);
else if(newTypes[i] == typeof(TrackingStatus))
newRow[i] = TrackingStatus.FromObject(oldRow[i]);
else if(newTypes[i] == typeof(EmailAddress))
newRow[i] = EmailAddress.FromObject(oldRow[i]);
}
convertedTable.Rows.Add(newRow);
}
// Bind the GridView.
displayGrid.DataSource = convertedTable;
displayGrid.DataBind();
2 个解决方案
#1
1
Instead of creating a new datatable when you convert each to custom types, create a new List and bind the list to the datasource. e.g.
将每个转换为自定义类型时,不是创建新的数据表,而是创建一个新的List并将列表绑定到数据源。例如
var list = new List<MyClass>();
var myType = //Convert your type
list.Add(myType);
grid.DataSource = list;
And ofcourse this all is just an idea of how to do it.
当然,这只是一个如何做到这一点的想法。
UPDATE: Saw your code afterwards:
更新:之后看到你的代码:
Try this:
尝试这个:
Create a class called ImportRow
创建一个名为ImportRow的类
class ImportRow
{
private string m_Status = string.Empty;
private DateTime m_DateOrdered;
private DateTime m_DateDue;
public ImportRow() { }
public string Status
{
get { return m_Status; }
set { m_Status = value; }
}
public DateTime DateOrdered
{
get { return m_DateOrdered; }
set { m_DateOrdered = value; }
}
public DateTime DateDue
{
get { return m_DateDue; }
set { m_DateDue = value; }
}
}
Then use it as:
然后用它作为:
var importedData = new List<ImportRow>();
foreach (DataRow oldRow in originalTable.Rows)
{
var newRow = new ImportRow();
newRow.Status = oldRow["status"].ToString();
newRow.DateDue = Convert.ToDateTime(oldRow["date_due"].ToString());
newRow.DateOrdered = Convert.ToDateTime(oldRow["date_ordered"].ToString());
importedData.Add(newRow);
}
Then
然后
displayGrid.DataSource = importedData;
displayGrid.DataBind();
#2
1
Your custom type needs public properties like these:
您的自定义类型需要以下公共属性:
public class Foo
{
public int Id;
public string Name;
}
or you need to use the DataTable
itself as DataSource
.
或者您需要将DataTable本身用作DataSource。
#1
1
Instead of creating a new datatable when you convert each to custom types, create a new List and bind the list to the datasource. e.g.
将每个转换为自定义类型时,不是创建新的数据表,而是创建一个新的List并将列表绑定到数据源。例如
var list = new List<MyClass>();
var myType = //Convert your type
list.Add(myType);
grid.DataSource = list;
And ofcourse this all is just an idea of how to do it.
当然,这只是一个如何做到这一点的想法。
UPDATE: Saw your code afterwards:
更新:之后看到你的代码:
Try this:
尝试这个:
Create a class called ImportRow
创建一个名为ImportRow的类
class ImportRow
{
private string m_Status = string.Empty;
private DateTime m_DateOrdered;
private DateTime m_DateDue;
public ImportRow() { }
public string Status
{
get { return m_Status; }
set { m_Status = value; }
}
public DateTime DateOrdered
{
get { return m_DateOrdered; }
set { m_DateOrdered = value; }
}
public DateTime DateDue
{
get { return m_DateDue; }
set { m_DateDue = value; }
}
}
Then use it as:
然后用它作为:
var importedData = new List<ImportRow>();
foreach (DataRow oldRow in originalTable.Rows)
{
var newRow = new ImportRow();
newRow.Status = oldRow["status"].ToString();
newRow.DateDue = Convert.ToDateTime(oldRow["date_due"].ToString());
newRow.DateOrdered = Convert.ToDateTime(oldRow["date_ordered"].ToString());
importedData.Add(newRow);
}
Then
然后
displayGrid.DataSource = importedData;
displayGrid.DataBind();
#2
1
Your custom type needs public properties like these:
您的自定义类型需要以下公共属性:
public class Foo
{
public int Id;
public string Name;
}
or you need to use the DataTable
itself as DataSource
.
或者您需要将DataTable本身用作DataSource。