有时候我们想将数组的内容显示在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 姓名 As String
Public 学号 As String
Public 年龄 As Integer
Public 性别 As String
End Class
上面定义为什么用中文?主要是为了在DataGrid是显示方便。为了方便地将数组转换为对象数组,我们再建一个类:
Private _Items(-1) As StudentBase '这个就是下面要用到的对象数组了
Public ReadOnly Property Items()Property Items() As StudentBase()
Get
Return _Items
End Get
End Property
Public Sub Add()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
三、将示例的数据转换为对象数组
With mStudent
.Add("马晓锋", "A001005", 15, "男")
.Add("刚小鸣", "A002008", 14, "男")
.Add("薛兰微", "A002004", 16, "女")
.Add("东望凉", "A001002", 15, "男")
.Add("王苍岳", "A002009", 15, "女")
End With
四、将对象数组转化为表(DataTable)的静态类
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()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()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()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
五、试试看
Table = ArrayToTable.Convert(mStudent.Items)
Me.DataGrid1.DataSource = Table
Me.DataGrid1.CaptionText = Table.TableName
Inherits System.Windows.Forms.Form
Windows 窗体设计器生成的代码#Region " Windows 窗体设计器生成的代码 "
Public Sub New()Sub New()
MyBase.New()
'该调用是 Windows 窗体设计器所必需的。
InitializeComponent()
'在 InitializeComponent() 调用之后添加任何初始化
End Sub
'窗体重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub Dispose()Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Windows 窗体设计器所必需的
Private components As System.ComponentModel.IContainer
'注意: 以下过程是 Windows 窗体设计器所必需的
'可以使用 Windows 窗体设计器修改此过程。
'不要使用代码编辑器修改它。
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.DataGrid1 = New System.Windows.Forms.DataGrid
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.Button1.Location = New System.Drawing.Point(40, 32)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(248, 40)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'DataGrid1
'
Me.DataGrid1.DataMember = ""
Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.DataGrid1.Location = New System.Drawing.Point(48, 120)
Me.DataGrid1.Name = "DataGrid1"
Me.DataGrid1.Size = New System.Drawing.Size(528, 344)