水如烟

                 顺其自然,水到渠成 LzmTW

文或代码皆是面向初学者.我是爱好者,也是初学者.那些"文章",只按自己理解写,我是不知术语名词的.所以只供参考,也仅供参考.

导航

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

Posted on 2005-10-17 00:32  水如烟(LzmTW)  阅读(1361)  评论(4编辑  收藏  举报
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