2009-08-07 36 views
1

我創建了從DataTable繼承的類。我想從類中揭示「名稱」,「數字」如何在DataTable中公開Column

。就像這樣

class MyClass : DataTable 
{ 
    [Column] 
    Name 

    [Column] 
    Number 
} 

這樣我就可以像行一樣訪問[「Name」] =「some」;

我打算使用這個數據表作爲DataSource來Crystal Report。 (即從數據菜單 - >添加新的數據源 - >對象,並選擇適當的類,這將顯示名稱和數字,我可以添加到水晶報告在設計時間)

如何實現這一目標。

+0

您是否在嘗試創建自己的強類型數據集? – 2009-08-07 15:23:30

+0

我不認爲我理解你,你描述的與DataTable和DataRow的默認行爲有什麼不同? – 2009-08-07 15:27:30

+0

您正在使用哪種版本的.NET框架? – 2009-08-07 15:35:26

回答

3

你正在重新發明輪子。試圖創建一個將公開命名行/列的DataTable是已經在.NET 2.0中完成的模式 - 如果您使用的是.NET 2.0,請查看此MSDN tutorial,該代碼將創建Strongly Typed DataSets。

您也可以使用谷歌的關鍵字Strong Typed DataSets

2

使用類型DataSet尋找更多的信息,要做到這一點的最好辦法。但在某些情況下,您可能不想或不能這樣做。例如,您可能需要屬性爲可空類型,其類型爲DataSet不支持。 (在輸入DataSet,每個空列也有Set<ColumnName>NullIs<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看看這是如何工作的。