如何于DataGridView中使用计算字段
2006-12-15 09:57:18
版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。 |
![]() 图表1
![]() 图表2
读者呆呆询问了好几次如何于DataGridView控件中使用计算字段的问题。在此我们就通过一个完整的范例一次清楚呈现。事实上,如果绑定至一个数据来源的DataGridView控件还必须内含计算字段的话,必须让DataGridView控件采用虚拟模式(也就是必须将 VirtualMode 属性设定成 True),而且您必须自行在CellValueNeeded事件处理例程中完成运算字段值的撷取作业。
图表1所示者是我们所撰写的程序范例,您可以在其中的DataGridView控件中新增、修改与删除数据,重点在于,其中的「年龄」资料行是根据「出生日期」计算而来。而且每当您更改「出生日期」数据行中的日期值,则在移出该储存格(Cell)后,年龄就会立即计算出来,即使是新增的数据记录也会如此。以下我们说明本程序范例的设计技巧。
首先,您必须如图表2所示,在窗体上加入所需的各个控件,然后撰写下列程序代码。我们是将窗体的程序代码全数列出,其中已加上完整的批注,另外,本程序使用到frmStatus.vb,因此务必记得将此文件汇入您的项目中:
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 ' 设定「出生日期」字段的默认值。 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 本文出自 “章立民” 博客,转载请与作者联系! 本文出自 51CTO.COM技术博客 |





章立民
博客统计信息
热门文章
最新评论
友情链接