HOW TO:对象数组转换为表(DataTable)

Author:水如烟
有时候我们想将数组的内容显示在DataGrid上。怎么做呢,MSDN关于DataGrid的说明上说,“也可以将 DataGrid 绑定到 ArrayListArrayList 的一个功能是它可以包含多种类型的对象,但当列表中的所有项与第一项具有相同的类型时,DataGrid 只能绑定到这类列表。这意味着所有的对象必须是同一种类型,或者必须从与列表中第一项相同的类继承。例如,如果列表中的第一项为 Control,则第二项可能为 TextBox(它从 Control 继承)。另一方面,如果第一项为 TextBox,则第二个对象就不可能是 Control。此外,ArrayList 在绑定时必须包含项目。空 ArrayList 会导致空网格。当绑定到 ArrayList 时,请将 DataGridTableStyle MappingName 设置为“ArrayList”(类型名)”。相关的示例有,只是具体的出处我忘了。以下提供另一种方法,就是将数组转换为对象数组(如果已经是对象数组那更好),再转换为表(DataTable)。当然,按我的习惯,转换方法肯定是通用的。

一、示例数据

用一组表示学生基本信息的数据吧。数据意义:姓名,学号,性别,年龄。(以下数据如有雷同,纯属巧合,请勿对号入座)
马晓锋,A001005,15,男
刚小鸣,A002008,14,男
薛兰微,A002004,16,女
东望凉,A001002,15,男
王苍岳,A002009,15,女

二、建相应的类(对象)

Public   Class StudentBase
    
Public 姓名 As String
    
Public 学号 As String
    
Public 年龄 As Integer
    
Public 性别 As String 
End Class

上面定义为什么用中文?主要是为了在DataGrid是显示方便。为了方便地将数组转换为对象数组,我们再建一个类:

Public   Class Student
    
Private _Items(-1As StudentBase '这个就是下面要用到的对象数组了
    Public ReadOnly Property Items() As StudentBase()
        
Get
            
Return _Items
        
End Get
    
End Property

    
Public Sub Add(ByVal Name As StringByVal NO As StringByVal Age As IntegerByVal Sex As String'添加一个学生
        Dim mItem As New StudentBase
        
With mItem
            .姓名 
= Name
            .学号 
= NO
            .年龄 
= Age
            .性别 
= Sex
        
End With

        
Dim i As Integer = _Items.Length
        
ReDim Preserve _Items(i)
        _Items(i) 
= mItem
    
End Sub

End Class


三、将示例的数据转换为对象数组
         Dim  mStudent  As   New  Student
        
With  mStudent
            .Add(
" 马晓锋 " " A001005 " 15 " " )
            .Add(
" 刚小鸣 " " A002008 " 14 " " )
            .Add(
" 薛兰微 " " A002004 " 16 " " )
            .Add(
" 东望凉 " " A001002 " 15 " " )
            .Add(
" 王苍岳 " " A002009 " 15 " " )
        
End   With
四、将对象数组转化为表(DataTable)的静态类
Public   Class ArrayToTable 
    
Private Shared _Columns As DataColumn() 
    
Private Shared _Items As Object() 
    
Private Shared _Table As DataTable 
    
Private Shared _TableName As String 

    
'这个静态类仅此函数是公开的,返回一个DataTable 
    Public Shared Function Convert(ByVal Items As Object()) As DataTable 
        _Table 
= Nothing 
        _Items 
= Items 
        
If _Items Is Nothing OrElse _Items.Length = 0 Then Return Nothing 
        
'用对象数组的第一项做参考生成DataTable 
        If Not GetDataColumn(_Items(0).GetType) Then Return Nothing 
        AddRow() 
        
Return _Table 
    
End Function
 

    
'根据Item的信息生成一个DataTable 
    Private Shared Function GetDataColumn(ByVal t As Type) As Boolean 
        
If t.GetFields.Length = 0 Then Return False 
        
ReDim _Columns(t.GetFields.Length) 
        
'取类名为Table名 
        _TableName = t.ToString.Substring(t.ToString.LastIndexOf("+"c) + 1
        
'加一序号。可以做成是否选择加序号,我这里加定了。 
        Dim c As DataColumn 
        c 
= New DataColumn 
        
With c 
            .ColumnName 
= "序号" 
            .DataType 
= GetType(Integer
            .AutoIncrement 
= True 
            .AutoIncrementSeed 
= 1 
        
End With 
        _Columns(
0= c 
        
'加列信息 
        Dim i As Integer = 0 
        
Dim f As System.Reflection.FieldInfo 
        
For Each f In t.GetFields 
            c 
= New DataColumn 
            i 
+= 1 
            
With c 
                .ColumnName 
= f.Name 
                .DataType 
= f.FieldType 
                _Columns(i) 
= c 
            
End With 
        
Next 
        
'创建Table实例 
        _Table = New DataTable(_TableName) 
        _Table.Columns.AddRange(_Columns) 
        
Return True 
    
End Function
 

    
'遍历对象数组,每一项作为一行添加到DataTable中去 
    Private Shared Sub AddRow() 
        
Dim o As Object 
        
Dim f As System.Reflection.FieldInfo 
        
For Each o In _Items 
            
Dim r As DataRow = _Table.NewRow 
            
For Each f In o.GetType.GetFields 
                r(f.Name) 
= f.GetValue(o) 
            
Next 
            _Table.Rows.Add(r) 
        
Next 
        _Table.AcceptChanges() 
    
End Sub
 
End Class
五、试试看
         Dim  Table  As  DataTable
        Table 
=  ArrayToTable.Convert(mStudent.Items)
        
Me .DataGrid1.DataSource  =  Table
        
Me .DataGrid1.CaptionText  =  Table.TableName
以下为全部代码。
Public   Class Form1 
    
Inherits System.Windows.Forms.Form 
Windows 窗体设计器生成的代码 
 
 
    
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
        
Dim mStudent As New Student 
        
With mStudent 
            .Add(
"马晓锋""A001005"15""
            .Add(
"刚小鸣""A002008"14""
            .Add(
"薛兰微""A002004"16""
            .Add(
"东望凉""A001002"15""
            .Add(
"王苍岳""A002009"15""
        
End With 
 
        
Dim Table As DataTable 
        Table 
= ArrayToTable.Convert(mStudent.Items) 
        
Me.DataGrid1.DataSource = Table 
        
Me.DataGrid1.CaptionText = Table.TableName 
    
End Sub
 
 
End Class
 
 
 
Public   Class StudentBase 
    
Public 姓名 As String 
    
Public 学号 As String 
    
Public 年龄 As Integer 
    
Public 性别 As String 
End Class
 
 
Public   Class Student 
    
Private _Items(-1As StudentBase '这个就是下面要用到的对象数组了 
    Public ReadOnly Property Items() As StudentBase() 
        
Get 
            
Return _Items 
        
End Get 
    
End Property
 
 
    
Public Sub Add(ByVal Name As StringByVal NO As StringByVal Age As IntegerByVal Sex As String'添加一个学生 
        Dim mItem As New StudentBase 
        
With mItem 
            .姓名 
= Name 
            .学号 
= NO 
            .年龄 
= Age 
            .性别 
= Sex 
        
End With 
        
Dim i As Integer = _Items.Length 
        
ReDim Preserve _Items(i) 
        _Items(i) 
= mItem 
    
End Sub
 
End Class
 
 
Public   Class ArrayToTable 
    
Private Shared _Columns As DataColumn() 
    
Private Shared _Items As Object() 
    
Private Shared _Table As DataTable 
    
Private Shared _TableName As String 
 
    
'这个静态类仅此函数是公开的,返回一个DataTable 
    Public Shared Function Convert(ByVal Items As Object()) As DataTable 
        _Table 
= Nothing 
        _Items 
= Items 
        
If _Items Is Nothing OrElse _Items.Length = 0 Then Return Nothing 
        
'用对象数组的第一项做参考生成DataTable 
        If Not GetDataColumn(_Items(0).GetType) Then Return Nothing 
        AddRow() 
        
Return _Table 
    
End Function
 
 
    
'根据Item的信息生成一个DataTable 
    Private Shared Function GetDataColumn(ByVal t As Type) As Boolean 
        
If t.GetFields.Length = 0 Then Return False 
        
ReDim _Columns(t.GetFields.Length) 
        
'取类名为Table名 
        _TableName = t.ToString.Substring(t.ToString.LastIndexOf("+"c) + 1
        
'加一序号。可以做成是否选择加序号,我这里加定了。 
        Dim c As DataColumn 
        c 
= New DataColumn 
        
With c 
            .ColumnName 
= "序号" 
            .DataType 
= GetType(Integer
            .AutoIncrement 
= True 
            .AutoIncrementSeed 
= 1 
        
End With 
        _Columns(
0= c 
        
'加列信息 
        Dim i As Integer = 0 
        
Dim f As System.Reflection.FieldInfo 
        
For Each f In t.GetFields 
            c 
= New DataColumn 
            i 
+= 1 
            
With c 
                .ColumnName 
= f.Name 
                .DataType 
= f.FieldType 
                _Columns(i) 
= c 
            
End With 
        
Next 
        
'创建Table实例 
        _Table = New DataTable(_TableName) 
        _Table.Columns.AddRange(_Columns) 
        
Return True 
    
End Function
 
 
    
'遍历对象数组,每一项作为一行添加到DataTable中去 
    Private Shared Sub AddRow() 
        
Dim o As Object 
        
Dim f As System.Reflection.FieldInfo 
        
For Each o In _Items 
            
Dim r As DataRow = _Table.NewRow 
            
For Each f In o.GetType.GetFields 
                r(f.Name) 
= f.GetValue(o) 
            
Next 
            _Table.Rows.Add(r) 
        
Next 
        _Table.AcceptChanges() 
    
End Sub
 
End Class
 


你可能感兴趣的:(Datatable)