您的位置:首页 > 职场人生

如何于DataGridView中使用计算字段

2006-12-15 09:57 417 查看


图表1



图表2

读者呆呆询问了好几次如何于DataGridView控件中使用计算字段的问题。在此我们就通过一个完整的范例一次清楚呈现。事实上,如果绑定至一个数据来源的DataGridView控件还必须内含计算字段的话,必须让DataGridView控件采用虚拟模式(也就是必须将 VirtualMode 属性设定成 True),而且您必须自行在CellValueNeeded事件处理例程中完成运算字段值的撷取作业。

图表1所示者是我们所撰写的程序范例,您可以在其中的DataGridView控件中新增、修改与删除数据,重点在于,其中的「年龄」资料行是根据「出生日期」计算而来。而且每当您更改「出生日期」数据行中的日期值,则在移出该储存格(Cell)后,年龄就会立即计算出来即使是新增的数据记录也会如此。以下我们说明本程序范例的设计技巧。

首先,您必须如图表2所示,在窗体上加入所需的各个控件,然后撰写下列程序代码。我们是将窗体的程序代码全数列出,其中已加上完整的批注,另外,本程序使用到frmStatus.vb,因此务必记得将此文件汇入您的项目中:

[align=left]Option Strict On
Imports System.Data.SqlClient
Imports System.IO
Public Class CH13_DemoForm001

Private myDataSet As DataSet

Private Sub CH13_DemoForm001_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' 呼叫 LoadDataToDataSet() 函式来连接至数据来源并传回所需的 DataSet 对象。
myDataSet = LoadDataToDataSet()

If myDataSet IsNot Nothing Then

' 将 BindingSource 组件系结至数据集对象中的「章立民研究室」数据表。
Me.BindingSource1.DataMember = "章立民研究室"
Me.BindingSource1.DataSource = myDataSet

' 将 BindingNavigator 控件的数据来源也设定成 BindingSource 组件,如此一来,
' 就可以使用 BindingNavigator 控件去导览 DataGridView 控件中的数据列。
Me.BindingNavigator1.BindingSource = Me.BindingSource1

' 自订 DataGridView 控件。
CustomizeMyDataGridView()
End If
End Sub

Private Sub CustomizeMyDataGridView()

' 由于我们要自订各个数据行类型,因此必须
' 将 AutoGenerateColumns 属性设定成 False。
DataGridView1.AutoGenerateColumns = False

' 设定奇数资料列的背景色。
DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = _
SystemColors.InactiveCaptionText

' 设定用户一次只能选取一个储存格、数据列或数据行。
DataGridView1.MultiSelect = False

' 设定采用储存格选取模式。
DataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect

' 设定数据列的高度。
Me.DataGridView1.RowTemplate.Height = 30

' 由于我们的 DataGridView 控件将会内含未系结数据行,因此必须 ' VirtualMode 属性设定成True,也就是必须启用虚拟模式。 DataGridView1.VirtualMode = True
' 将 DataGridView 控件的数据来源设定成 BindingSource 组件。
Me.DataGridView1.DataSource = Me.BindingSource1

' 接下来的程序代码要自订各个数据行类型.....

'
' 资料行:员工编号,文字方块
'
' 建立一个 DataGridViewTextBoxColumn 对象并设定其相关属性。
'
Dim colEmployeeId As New DataGridViewTextBoxColumn()
' 设定来源字段。
colEmployeeId.DataPropertyName = "员工编号"
' 设定数据行标题。
colEmployeeId.HeaderText = "编号"
colEmployeeId.Name = "员工编号"
' 将此数据行设定成只读的。
colEmployeeId.ReadOnly = True
' 设定数据行的宽度。
colEmployeeId.Width = 60
' 将 DataGridViewTextBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colEmployeeId)

'
' 资料行:姓名,文字方块
'
' 建立一个 DataGridViewTextBoxColumn 对象并设定其相关属性。
'
Dim colName As New DataGridViewTextBoxColumn()
' 调整资料行的宽度使其足以显示出最宽的可见储存格(包括标题在内)。
colName.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
' 设定来源字段。
colName.DataPropertyName = "姓名"
' 设定数据行标题。
colName.HeaderText = "员工姓名"
colName.Name = "姓名"
colName.ReadOnly = False
' 将 DataGridViewTextBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colName)

'
' 资料行:性别,下拉式清单方块
'
' 建立一个 DataGridViewComboBoxColumn 对象并设定其相关属性。
'
Dim colGender As New DataGridViewComboBoxColumn()
' 调整资料行的宽度使其足以显示出标题。
colGender.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
' 设定来源字段。
colGender.DataPropertyName = "性别"
' 设定下拉式清单中的选项。
colGender.Items.AddRange(New String() {"男", "女"})
' 排序下拉式清单方块的内容。
colGender.Sorted = True
' 停用数据行的排序功能。
colGender.SortMode = DataGridViewColumnSortMode.NotSortable
colGender.HeaderText = "性别"
colGender.Name = "性别"
colGender.ReadOnly = False
' 将 DataGridViewComboBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colGender)

'
' 资料行:出生日期,自订格式化的文字方块
'
' 建立一个 DataGridViewTextBoxColumn 对象并设定其相关属性。
'
Dim colBirthday As New DataGridViewTextBoxColumn()
' 调整资料行的宽度使其足以显示出最宽的可见储存格(包括标题在内)。
colBirthday.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
' 设定来源字段。
colBirthday.DataPropertyName = "出生日期"
' 设定日期显示格式。
colBirthday.DefaultCellStyle.Format = "MM-dd-yyyy"
colBirthday.HeaderText = "出生月日年"
colBirthday.Name = "出生日期"

' 将 DataGridViewTextBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colBirthday)

'
' 资料行:年龄,未系结的资料行
'
' 建立一个 DataGridViewTextBoxColumn 对象并设定其相关属性。
'
Dim colAge As New DataGridViewTextBoxColumn() ' 调整资料行的宽度使其足以显示出标题。 colAge.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader colAge.HeaderText = "年龄" colAge.Name = "年龄" ' 将此资料行设定成只读,毕竟年龄是根据出生日期所计算出来。 ' 如果没有将此数据行设定成只读,则必须通过 CellValuePush 事件处理例程 ' 将所输入的数据写入数据来源。 colAge.ReadOnly = True ' 设定当引发 DataGridView 控件的 CellValueNeeded 事件时所要执行的 ' 事件处理例程。请特别注意,未系结资料行是通过CellValueNeeded 事件 ' 来撷取资料。 AddHandler DataGridView1.CellValueNeeded, AddressOf colAge_CellValueNeeded
' 将 DataGridViewTextBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colAge)

'
' 资料行:婚姻状况,下拉式清单方块
'
' 建立一个 DataGridViewComboBoxColumn 对象并设定其相关属性。
'
Dim colMaritalStatus As New DataGridViewComboBoxColumn()
' 调整资料行的宽度使其足以显示出标题。
colMaritalStatus.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
' 设定来源字段。
colMaritalStatus.DataPropertyName = "婚姻状况"
' 设定下拉式清单中的选项。
colMaritalStatus.Items.AddRange(New String() {"已婚", "未婚"})
' 排序下拉式清单方块的内容。
colMaritalStatus.Sorted = True
' 停用数据行的排序功能。
colMaritalStatus.SortMode = DataGridViewColumnSortMode.NotSortable
colMaritalStatus.HeaderText = "婚姻状况"
colMaritalStatus.Name = "婚姻状况"
colMaritalStatus.ReadOnly = False
' 将 DataGridViewTextBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colMaritalStatus)

'
' 资料行:部门,下拉式清单方块
'
' 建立一个 DataGridViewComboBoxColumn 对象并设定其相关属性。
'
' 请注意,此数据行之下拉式清单方块的选项内容是来自数据集 myDataSet
' 当中的「公司部门」资料表。
'
Dim colDepartment As New DataGridViewComboBoxColumn()
colDepartment.DataPropertyName = "部门"
' 将下拉式清单方块系结至数据集 myDataSet 当中的「公司部门」资料表。
colDepartment.DataSource = myDataSet.Tables("公司部门")
colDepartment.ValueMember = "部门"
colDepartment.DisplayMember = "部门"
colDepartment.HeaderText = "任职部门"
colDepartment.Name = "部门"
colDepartment.ReadOnly = False
colDepartment.Width = 120
' 将 DataGridViewComboBoxColumn 对象新增至 DataGridView 控件的数据行集合中。
DataGridView1.Columns.Add(colDepartment)
End Sub

' 此事件处理例程负责替未系结数据行撷取数据。
Private Sub colAge_CellValueNeeded(ByVal sender As Object, _
ByVal e As DataGridViewCellValueEventArgs)

If e.ColumnIndex = CType(sender, DataGridView).Columns("年龄").Index Then
Dim age As Integer
Dim birthDate As DateTime = _
CDate(CType(sender, DataGridView).Rows( _
e.RowIndex).Cells("出生日期").Value)
age = DateTime.Today.Year - birthDate.Year

If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
age -= 1
End If
e.Value = age
End If
End Sub

Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
Handles DataGridView1.CellEndEdit
If e.ColumnIndex = CType(sender, DataGridView).Columns("出生日期").Index Then
Dim age As Integer
Dim birthDate As DateTime = CDate(CType( _
sender, DataGridView).Rows(e.RowIndex).Cells("出生日期").Value)
age = DateTime.Today.Year - birthDate.Year

If (DateTime.Today.DayOfYear < birthDate.DayOfYear) Then
age -= 1
End If
CType(sender, DataGridView).Rows( _
e.RowIndex).Cells("年龄").Value = age.ToString

End If
End Sub
' 本程序会连接至数据来源并建立所需的 DataSet 对象。
Private Function LoadDataToDataSet() As DataSet
' 利用 SqlConnectionStringBuilder 对象来构建连接字符串。
Dim sqlStringBuilder As New SqlConnectionStringBuilder()
sqlStringBuilder.DataSource = "(local)\SQLEXPRESS"
sqlStringBuilder.InitialCatalog = "北风贸易"
sqlStringBuilder.IntegratedSecurity = True

' 建立一个数据集。
Dim ds As New DataSet()

' 显示一个状态讯息对话框来表示我们目前要尝试连结至 SQL Server Express。
Dim frmStatusMessage As New frmStatus

frmStatusMessage.Show("连接至SQL Server Express 中....")

Try
Using northwindConnection As _
New SqlConnection(sqlStringBuilder.ConnectionString)

Dim cmdLiming As New SqlCommand( _
"SELECT DISTINCT 部门FROM dbo.章立民研究室;" & _
"SELECT 员工编号,姓名,性别,婚姻状况,部门,出生日期,玉照 " & _
"FROM dbo.章立民研究室", northwindConnection)

northwindConnection.Open()

Using drLiming As SqlDataReader = cmdLiming.ExecuteReader()

ds.Load( _
drLiming, _
LoadOption.OverwriteChanges, _
New String() {"公司部门", "章立民研究室"})

End Using
End Using

' 设定「出生日期」字段的默认值。[/align]
[align=left] ds.Tables("章立民研究室").Columns("出生日期").DefaultValue = DateTime.Now

Catch exc As Exception

frmStatusMessage.Close()

MessageBox.Show( _
"要能够顺利执行本范例程序,您的计算机必须已安装SQL Server " & _
"Express,并且必须已附加了本书所附的「北风贸易」数据库。" & _
"关于如何安装SQL Server Express,请参阅附录或相关文件说明。")

' 无法连接至SQL Server。
Return Nothing
End Try

frmStatusMessage.Close()
Return ds
End Function

End Class[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐