我创建了从DataTable继承的类。我想公开像“姓名”,“数字”
这样的项目来自班级。就像这样
class MyClass : DataTable
{
[Column]
Name
[Column]
Number
}
这样我就可以访问行[“Name”] =“some”;
我将使用此数据表作为Crystal Report的DataSource。 (即从数据菜单 - >添加新的DataSource - >对象并选择适当的类,这将显示我可以在设计时添加到水晶报表的名称和编号)
如何实现这一目标。
答案 0 :(得分:3)
你正在重新发明轮子。尝试创建一个将公开命名行/列的DataTable是一种已在.NET 2.0中完成的模式 - 如果您使用的是.NET 2.0,请查看此MSDN tutorial,其中包括创建强类型数据集。
您还可以使用关键字Strong Typed DataSets
在Google上搜索更多信息答案 1 :(得分:2)
使用键入的DataSet
是执行此操作的最佳方式。但在某些情况下,您可能不希望或无法做到这一点。例如,您可能需要将属性设置为可空类型,键入的DataSet
不支持这些类型。 (在键入的DataSet
中,每个可以为空的列也有Set<ColumnName>Null
和Is<ColumnName>Null
方法,这非常可怕。)
在这些情况下,您希望采用与键入的DataSet
采用的方法相同的方法:子类DataRow
并在那里实现属性,例如:
public class MyDataRow : DataRow
{
public DateTime? SomeDate
{
get
{
return (this["SomeDate"] is DBNull)
? (DateTime?)null
: this.Field<DateTime>("SomeDate");
}
set
{
if (value == null)
{
this["SomeDate"] = DBNull.Value;
}
else
{
this["SomeDate"] = value;
}
}
}
}
有两件事情使这一点复杂化,它们与新行的构造方式有关。首先,您必须在MyDataTable
中实现一个调用基础构造函数的构造函数:
public MyDataRow(DataRowBuilder rb) : base(rb) { }
第二个(这是令人困惑的部分),您还必须继承DataTable
并覆盖NewRowFromBuilder
方法。这使得NewRow
方法返回DataRow
对象,该对象实际上是MyDataRow
对象(因为NewRow
调用NewRowFromBuilder
)。如果您不这样做,NewRow
将调用基类的NewRowFromBuilder
实现,该实现返回DataRow
,您需要它返回MyDataRow
。
public class MyDataTable : DataTable
{
protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
{
return new MyDataRow(builder);
}
}
然后在代码中创建这些对象,你有这样的东西:
MyDataTable t = new MyDataTable();
MyDataRow r = (MyDataRow) t.NewRow();
请注意,您仍然必须从NewRow
转换返回值(因为NewRow
始终返回DataRow
类型的对象。
如果您需要处理MyDataTable
上的事件,则需要覆盖事件处理程序,并让它们在MyDataRow
对象中引发事件。实际上,您应该查看已键入的DataSet
生成的代码,以了解其工作原理。