Author:水如烟
有时候我们想将数组的内容显示在DataGrid上。怎么做呢,MSDN关于DataGrid的说明上说,“也可以将 DataGrid 绑定到 ArrayList。ArrayList 的一个功能是它可以包含多种类型的对象,但当列表中的所有项与第一项具有相同的类型时,DataGrid 只能绑定到这类列表。这意味着所有的对象必须是同一种类型,或者必须从与列表中第一项相同的类继承。例如,如果列表中的第一项为 Control,则第二项可能为 TextBox(它从 Control 继承)。另一方面,如果第一项为 TextBox,则第二个对象就不可能是 Control。此外,ArrayList 在绑定时必须包含项目。空 ArrayList 会导致空网格。当绑定到 ArrayList 时,请将 DataGridTableStyle 的 MappingName 设置为“ArrayList”(类型名)”。相关的示例有,只是具体的出处我忘了。以下提供另一种方法,就是将数组转换为对象数组(如果已经是对象数组那更好),再转换为表(DataTable)。当然,按我的习惯,转换方法肯定是通用的。
三、将示例的数据转换为对象数组
有时候我们想将数组的内容显示在DataGrid上。怎么做呢,MSDN关于DataGrid的说明上说,“也可以将 DataGrid 绑定到 ArrayList。ArrayList 的一个功能是它可以包含多种类型的对象,但当列表中的所有项与第一项具有相同的类型时,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
Public 姓名 As String
Public 学号 As String
Public 年龄 As Integer
Public 性别 As String
End Class
上面定义为什么用中文?主要是为了在DataGrid是显示方便。为了方便地将数组转换为对象数组,我们再建一个类:
Public Class Student
Private _Items(-1) As StudentBase '这个就是下面要用到的对象数组了
Public ReadOnly Property Items() As StudentBase()
Get
Return _Items
End Get
End Property
Public Sub Add(ByVal Name As String, ByVal NO As String, ByVal Age As Integer, ByVal 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
Private _Items(-1) As StudentBase '这个就是下面要用到的对象数组了
Public ReadOnly Property Items() As StudentBase()
Get
Return _Items
End Get
End Property
Public Sub Add(ByVal Name As String, ByVal NO As String, ByVal Age As Integer, ByVal 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)的静态类With mStudent
.Add("马晓锋", "A001005", 15, "男")
.Add("刚小鸣", "A002008", 14, "男")
.Add("薛兰微", "A002004", 16, "女")
.Add("东望凉", "A001002", 15, "男")
.Add("王苍岳", "A002009", 15, "女")
End With
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
五、试试看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
以下为全部代码。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(-1) As StudentBase '这个就是下面要用到的对象数组了
Public ReadOnly Property Items() As StudentBase()
Get
Return _Items
End Get
End Property
Public Sub Add(ByVal Name As String, ByVal NO As String, ByVal Age As Integer, ByVal 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
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(-1) As StudentBase '这个就是下面要用到的对象数组了
Public ReadOnly Property Items() As StudentBase()
Get
Return _Items
End Get
End Property
Public Sub Add(ByVal Name As String, ByVal NO As String, ByVal Age As Integer, ByVal 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