经过一段时间的努力,并参阅了很多大侠的源代码,重新改造了一下DataGrid控件。现将所有的源代码全部公布,以和朋友们共享。
'主要的功能有:
' 可以显示汉字标题、列宽、左边行号;
' 可以按照标题行排序;
' 可以设置脚注汇总行(排序后仍然在最后一行);
' 表格中有右键菜单;
' 可以根据各单元格的数据类型,自动设置显示格式;
' 对于日期时间数据,可以只显示日期,也可显示时间;
' 对于逻辑型数据,用CheckBox显示数据
'主要的属性是:
'.BqColorFootBack 设置脚注合计行的背景颜色,如果不设,则与表格背景一致
'.BqColorFootFont 设置脚注合计行的字体颜色,如果不设,则与表格字体一致
'.BqcNoReadOnlyMap 设置哪此字段是可以编辑的,如果不设,则所有字段只读
'.BqColumnHeader 设置表格中各显示列的汉字标题,如果不设,则标题为空
'.BqColumnMap 设置表格中各显示列的字段名,如果不设,则显示数据源中所有字段
'.BqColumnWidth 设置表格中各显示列的宽度,如果不设,则自动列宽
'.BqSetSource 设置表格的数据源dataview。设置好上面的属性后,就可以用此属性进行初始化了。
'.BqMsetSum 设置并返回聚合函数的值,并在表格最后脚注栏显示
'.BqpshowAllColumnS 设置是否整行选中
'.BqpshowAutoWidths 设置是否自动列宽
'.BqpShowNull 设置是否显示空值
'.BqpShowNumber 设置是否显示左边的行号
'.BqpShowTime 设置是否显示完整的时间,否则只显示年月日
'例如:
' With BqUDataGrid1
' .BqColumnMap = "ID1,BHranKdq,BHdq,BHparent,MCdq,YB,QH,ZD,PYdq,K_dele"
' .BqColumnHeader = "ID,级别编号,地区编号,上级编号,地区名称,邮政编码,电话区号,驻地,拼音代码,停用"
' .BqColumnWidth = "0,40,60,0,120,60,0,80,50,30,100,150,50,80,100,150,50,60,50"
' .BqcNoReadOnlyMap = "MCdq,YB,QH,"
' .BqColorFootBack = Brushes.White
' .BqColorFootFont = Brushes.Tomato
' .BqSetSource = ltv
' End With
'还需要改进的是:
' 1、红字条件。即给定一个符合where规则的条件表达式,让控件用红色显示满足条件的记录;
' 2、返回记录。即随时返回当前的记录datarow,从而确定当前记录中各字段的值,并且还能判断是否满足条件
' 3、左边行号。如果能够把左边行号与表中的记录号一一对应就好了。
Imports System
Imports System.Collections
Imports Microsoft.visualbasic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Windows.Forms
Imports System.Text
全新打造的最新的datagrid 作者:钱波#Region " 全新打造的最新的datagrid 作者:钱波 "
'主要的功能有:
' 可以显示汉字标题、列宽、左边行号、可以按照标题行排序,可以设置脚注汇总行(排序后仍然在最后一行)、表格中有右键菜单
'主要的属性是:
'.BqColorFootBack 设置脚注合计行的背景颜色,如果不设,则与表格背景一致
'.BqColorFootFont 设置脚注合计行的字体颜色,如果不设,则与表格字体一致
'.BqcNoReadOnlyMap 设置哪此字段是可以编辑的,如果不设,则所有字段只读
'.BqColumnHeader 设置表格中各显示列的汉字标题,如果不设,则标题为空
'.BqColumnMap 设置表格中各显示列的字段名,如果不设,则显示数据源中所有字段
'.BqColumnWidth 设置表格中各显示列的宽度,如果不设,则自动列宽
'.BqSetSource 设置表格的数据源dataview。设置好上面的属性后,就可以用此属性进行初始化了。
'.BqMsetSum 设置并返回聚合函数的值,并在表格最后脚注栏显示
'.BqpshowAllColumnS 设置是否整行选中
'.BqpshowAutoWidths 设置是否自动列宽
'.BqpShowNull 设置是否显示空值
'.BqpShowNumber 设置是否显示左边的行号
'.BqpShowTime 设置是否显示完整的时间,否则只显示年月日
'例如:
' With BqUDataGrid1
' .BqColumnMap = "ID1,BHranKdq,BHdq,BHparent,MCdq,YB,QH,ZD,PYdq,K_dele"
' .BqColumnHeader = "ID,级别编号,地区编号,上级编号,地区名称,邮政编码,电话区号,驻地,拼音代码,停用"
' .BqColumnWidth = "0,40,60,0,120,60,0,80,50,30,100,150,50,80,100,150,50,60,50"
' .BqcNoReadOnlyMap = "MCdq,YB,QH,"
' .BqColorFootBack = Brushes.White
' .BqColorFootFont = Brushes.Tomato
' .BqSetSource = ltv
' End With
'还需要改进的是:
' 1、红字条件。即给定一个符合where规则的条件表达式,让控件用红色显示满足条件的记录;
' 2、返回记录。即随时返回当前的记录datarow,从而确定当前记录中各字段的值,并且还能判断是否满足条件
' 3、左边行号。如果能够把左边行号与表中的记录号一一对应就好了。
Public Class BqUDataGridClass BqUDataGrid
Inherits System.Windows.Forms.DataGrid
初始化时需要定义的属性和方法#Region " 初始化时需要定义的属性和方法 "
Public WriteOnly Property BqColumnMap()Property BqColumnMap() As String
Set(ByVal Value As String)
lColumnMap = Value 'MGsubStrings(Value)
End Set
End Property '
Public WriteOnly Property BqColumnHeader()Property BqColumnHeader() As String
Set(ByVal Value As String)
lColumnHeader = Value
End Set
End Property
Public WriteOnly Property BqColumnWidth()Property BqColumnWidth() As String
Set(ByVal Value As String)
lColumnWidth = Value
End Set
End Property
Public WriteOnly Property BqcNoReadOnlyMap()Property BqcNoReadOnlyMap() As String
Set(ByVal Value As String)
lMapOnly = Value
End Set
End Property '非只读的列名,即可以编辑的字段,毕竟是少数
Public WriteOnly Property BqConditiona()Property BqConditiona() As String
Set(ByVal Value As String)
lredConditiona = Value
End Set
End Property '指定条件,分颜色显示的条件
Public WriteOnly Property BqConditionaMap()Property BqConditionaMap() As String
Set(ByVal Value As String)
lMapRed = Value
End Set
End Property '指定条件,分颜色显示的列名
Public WriteOnly Property BqConditionaColor()Property BqConditionaColor() As Drawing.Color
Set(ByVal Value As Drawing.Color)
lredColor = Value
End Set
End Property '指定条件,设置颜色
Public Shared Property BqColorFootBack()Property BqColorFootBack() As Brush
Get
Return lColorFootBack
End Get
Set(ByVal Value As Brush)
lColorFootBack = Value
End Set
End Property '求和栏 脚注 背景色
Public Shared Property BqColorFootFont()Property BqColorFootFont() As Brush
Get
Return lColorFootFore
End Get
Set(ByVal Value As Brush)
lColorFootFore = Value
End Set
End Property '求和栏 脚注 字体色
#End Region
初始化结束后,可以调用的属性、方法、事件、函数#Region " 初始化结束后,可以调用的属性、方法、事件、函数"
Public WriteOnly Property BqSetSource()Property BqSetSource() As DataTable
Set(ByVal Value As DataTable)
If IsNothing(Value) Then Exit Property
MyDataTable = Nothing
MyDataView = Nothing
MyDataTable = Value
MyDataView = MyDataTable.DefaultView
MyDataView.RowFilter = ""
Call Mini()
End Set
End Property
Public WriteOnly Property BqpShowNumber()Property BqpShowNumber() As Boolean
Set(ByVal Value As Boolean)
lshowNumber = Value
If Value = True Then '显示行号
MsRowHeadr()
Else
Dim i As Integer
For i = 0 To Me.VisibleRowCount - 1
Me.CreateGraphics.DrawString("", Me.Font, New System.Drawing.SolidBrush(Me.ForeColor), 12, i)
'12是x坐标,目的是需要留下左边当前记录标志(三角形)的位置
Next
Call MsRowHeaderWidth(15)
Me.Refresh()
End If
End Set
End Property '显示行号 表格显示左侧编号
Public WriteOnly Property BqpShowNull()Property BqpShowNull() As Boolean '//不显示NULL
Set(ByVal Value As Boolean)
Dim c As DataGridColumnStyle
Dim t As DataGridTableStyle
For Each t In Me.TableStyles
For Each c In t.GridColumnStyles
If Value Then
c.NullText = ""
Else
c.NullText = "(null)"
End If
Next
Next
End Set
End Property '不显示NULL
Public WriteOnly Property BqpShowTime()Property BqpShowTime() As Boolean '//如果是日期类型,显示时间
Set(ByVal Value As Boolean)
Dim c As DataGridColumnStyle
Dim t As DataGridTableStyle
For Each t In Me.TableStyles
For Each c In t.GridColumnStyles
If Not c.MappingName = "" AndAlso MyDataTable.Columns(c.MappingName).DataType.Name.IndexOf("Date") <> -1 Then
If Value Then
CType(c, DataGridTextBoxColumn).Format = "yyyy-MM-dd hh:mm:ss "
Else
CType(c, DataGridTextBoxColumn).Format = "yyyy-MM-dd "
End If
End If
Next
Next
End Set
End Property '如果是日期类型,显示时间
Public WriteOnly Property BqpshowAutoWidths()Property BqpshowAutoWidths() As Boolean
Set(ByVal Value As Boolean)
Dim c As DataGridColumnStyle
Dim t As DataGridTableStyle
Dim n As Integer = 0
Debug.WriteLine("BqpshowAutoWidths 共自定义有N个列 ")
For Each t In Me.TableStyles
n = 0
For Each c In t.GridColumnStyles
c.Width = IIf(Value, bColumn(n).WidthiAutoI, bColumn(n).WidthI)
Debug.WriteLine(c.MappingName + " " + bColumn(n).MapS)
n = n + 1
Next
Next
Debug.WriteLine("BqpshowAutoWidths 共自定义有N个列 " + n.ToString)
End Set
End Property '是否自动显示列宽
Public WriteOnly Property BqpshowRedConditiona()Property BqpshowRedConditiona() As Boolean '是否根据条件显示
Set(ByVal Value As Boolean)
lshowRedConditiona = Value
Call MsShowRed()
End Set
End Property '指定条件,是否需要分颜色显示
Public WriteOnly Property BqpshowAllColumnS()Property BqpshowAllColumnS() As Boolean
Set(ByVal Value As Boolean)
lAllColumns = Value
End Set
End Property '是否整行选中
Public Function BqsetSum()Function BqsetSum(ByVal sField As String, ByVal lType_Avg_Count_Max_Min_Sum As String) As String
Dim m0, tj, js, s As String
Dim i, n As Integer
i = -1
n = MFindField(sField)
If n > -1 Then
For n = lnewCols To bColumn.Length - 1
If UCase(sField) = UCase(bColumn(n).MapS) Then
i = n
Exit For
End If
Next
End If
If i >= 0 Then '在表中找到这个字段,并且在显示中也找到这个字段
Dim k As String = Trim(UCase(lType_Avg_Count_Max_Min_Sum))
Select Case Trim(UCase(k))
Case "AVG" '列平均值
s = "Avg("
Case "COUNT" '列值的计数
s = "Count("
Case "MAX" '列中最大值 ,可针对文本
s = "Max("
Case "MIN" '列中最小值
s = "Min("
Case "SUM" '列值的合计
s = "Sum("
Case Else
s = "Sum("
End Select
Try
'MyDataTable.Columns(bADDsm).ReadOnly = False
MyNewDataRow.ItemArray = lNewRow
'MyDataTable.Columns(bADDsm).ReadOnly = True
Dim lCell As DataGridCell = New DataGridCell
lCell.RowNumber = MyDataTable.Rows.Count - 1
tj = bADDsm + " is null"
js = s + bColumn(i).MapS + ")"
m0 = MyDataTable.Compute(js, tj).ToString
lCell.ColumnNumber = n
Me(lCell) = m0
Catch ex As Exception
End Try
End If
Return m0
End Function
Public WriteOnly Property BqpSetSumS()Property BqpSetSumS() As String
Set(ByVal Value As String)
Try
'MyDataTable.Columns(bADDsm).ReadOnly = False
MyNewDataRow.ItemArray = lNewRow
'MyDataTable.Columns(bADDsm).ReadOnly = True
Dim lc(), ls(), ls2() As String
Dim i, n As Integer
lc = MgSplit(Value)
If Not IsNothing(lc) Then
For i = 0 To lc.Length - 1
ls = lc(i).Split("-")
If Not IsNothing(ls) Then
Try
BqsetSum(ls(0), ls(1))
Catch ex As Exception
End Try
End If
Next
End If
Catch ex As Exception
End Try
End Set
End Property
Public Property BqpTooltip()Property BqpTooltip() As String
Get
Return lTooltip
End Get
Set(ByVal Value As String)
lTooltip = Value
Me.oTooltip.SetToolTip(Me, Value)
End Set
End Property '指定提示信息
Public Event BqMSelectGrid() '外部设置,选择表格行后
Public ReadOnly Property BqpRowsCount()Property BqpRowsCount() As Integer
Get
Return RowCount - 1 '返回记录数,因为不需要新加的那个脚注行
End Get
End Property
#End Region
内部定义的变量、函数、过程#Region " 内部定义的变量、函数、过程"
Private Structure sBqColumnStructure sBqColumn '定义一个全局结构,每一列的相关的信息
Dim MapS As String '字段名
Dim HeaderS As String '汉字标题
Dim WidthI As Integer '宽度 像素
Dim ReadOnlyB As Boolean '是否只读
Dim RedB As Boolean '是否红字
Dim WidthiAutoI As Integer '自动时的宽度
Dim TypeS As String '数据类型,
'为建立列样式的方便,只设置“Boolean,DateTime,Integer,Decimal,String”五种
'因为: Boolean 逻辑型,需要用复选框类的列样式
'DateTime日期时间型 是日期格式
'Int32 长整型、Int16整型,Byte字节型 的格式不需要小数位数
'Decimal 小数、货币、单双精 需要设置小数倍数
'其它的都是String,不需要设置格式
End Structure
Dim lColumnMap As String '只是在设置属性是用此变量 需要显示的列 字段名
Dim lColumnHeader As String '只是在设置属性是用此变量 需要显示的列 汉字名
Dim lColumnWidth As String '只是在设置属性是用此变量 需要显示的列 宽度
Dim lMapOnly As String
Dim lMapRed As String '只是在设置属性是用此变量 ' 分颜色显示的列名
Dim lredConditiona As String = ""
Dim lredColor As Drawing.Color
Dim RowCount As Integer = 0
Dim ColCount As Integer = 0
Dim SortedColNum As Integer
Dim lynAscending As Boolean = False '当前排序的方式:true升序
Dim CellValueChanged As Boolean = False '是否改变当前单元格的值
Dim MyDataView As DataView
Dim MyNewDataRow As DataRow
Dim WithEvents MyDataTable As DataTable '带事件的对象
Dim CurrentDataGridCellLocation As DataGridCell = New DataGridCell
Shared lColorFootBack As Brush
Shared lColorFootFore As Brush
Dim lFirst As Boolean = True
Dim bColumn() As sBqColumn
Dim lnewCols As Integer = 3 '新增字段的个数,显示列的起始号
Dim bADDid As String = "lAddC4321id" '新增的每行的ID,即 编号 字段的名称
Dim bADDtj As String = "lAddC1234tj" '新增的每行的TJ,即 条件 字段的名称,保存该记录是否满足条件
Dim bADDsm As String = "lAddC4444sm" '新增的每行的sm,即 求和的列
Dim oMenu As New ContextMenu '一个右键菜单
Dim sMenu() As String
Dim lNewRow As Array
Dim lTooltip As String
Dim oTooltip As New ToolTip
Dim lYnWidthAuto As Boolean '是否强制自动列宽
Dim lshowNumber As Boolean '是否显示列号
Dim lAllColumns As Boolean '是否整行选中
Dim lshowRedConditiona As Boolean '是否根据条件显示
Dim lsumlist As String
Private Sub Mini()Sub Mini()
'Dim dlast As Long = System.Environment.TickCount()
'Dim ttt As Long = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("开始时间 " + dlast.ToString)
'Debug.WriteLine("开始时间 间隔: " + ttt.ToString)
Me.DataSource = MyDataView
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("1 间隔: " + ttt.ToString)
Call Me.Ma1ColuArray()
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("2 间隔: " + ttt.ToString)
Call Me.Ma2AddColumn() ' 添加列的工作只能做一次
'End If
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("3 间隔: " + ttt.ToString)
ColCount = MyDataTable.Columns.Count
RowCount = MyDataTable.Rows.Count
Call Ma3setHead()
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("4 间隔: " + ttt.ToString)
Call MsRowHeaderWidth(15)
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("5 间隔: " + ttt.ToString)
Call Ma4Menu()
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("6 间隔: " + ttt.ToString)
'Call Ma5setSum("")
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("7 间隔: " + ttt.ToString)
BqpShowNull = True '不显示空值
BqpShowTime = True
Me.DataSource = MyDataView
MyDataView.ApplyDefaultSort = False
MyDataView.AllowNew = False
lBM = BindingContext(MyDataView)
'Me.Select(RowCount - 1)
'ttt = System.Math.Abs(System.Environment.TickCount - dlast)
'Debug.WriteLine("8 间隔: " + ttt.ToString)
'ttt = System.Environment.TickCount
'Debug.WriteLine("结束时间: " + ttt.ToString)
End Sub
Private Sub Ma1ColuArray()Sub Ma1ColuArray()
'初始化每个字段数组,使得需要显示的字段的格式数据化
'根据外部定义的属性来读取正确的数组初值
Dim n, i, k As Integer
Dim s As String
Dim nLeng As Integer
nLeng = MyDataTable.Columns.Count - 1 '此时表示 表的字段数
Try
Dim lc(), lcw(), lch() As String
lc = MgSplit(lColumnMap)
If Not IsNothing(lc) Then
For i = 0 To lc.Length - 1 '去除重复的字段名称,目的的下面计算字段数是比较准确
s = Trim(UCase(lc(i)))
For n = i + 1 To lc.Length - 1
If s.Length > 0 And s = Trim(UCase(lc(n))) Then ' 如果字段名非空,并且与后面的都不相同
lc(n) = " "
End If
Next
Next
Else
s = ""
For i = 0 To nLeng
s = s + MyDataTable.Columns(i).ColumnName + ","
Next
lColumnMap = s
lc = Nothing
lc = MgSplit(lColumnMap)
End If
k = -1
For i = 0 To lc.Length - 1 '计算字段名数组中,在数据源中的字段数(可能有部分名称没在数据源中)
If MFindField(Trim(lc(i))) >= 0 Then
k = IIf(lc(i) = bADDid Or lc(i) = bADDtj, k, k + 1) '不计新加的字段
End If
Next
If k = -1 Then '所给的字段全部不存在,则显示所有的字段
s = ""
For i = 0 To nLeng
s = s + MyDataTable.Columns(i).ColumnName + ","
Next
lColumnMap = s
Else
nLeng = k '得到字段的个数,不包括新加的字段
End If
'nLeng '此时表示,有效的字段数,即包括在数据源中的字段数
ReDim bColumn(nLeng + lnewCols)
k = nLeng + lc.Length + 100
ReDim lcw(k), lch(k) '需要多定义一些才行,方便与字段名对应,如果字段名不可用,则汉字名和宽度也不用
'先取出宽度和汉字标题,新增的三个字段不显示
For i = 0 To k
lcw(i) = "40"
lch(i) = " "
Next
lc = Nothing '依次取宽度
lc = MgSplit(lColumnWidth)
If Not IsNothing(lc) Then
k = Math.Min(lc.Length, lcw.Length) - 1
For i = 0 To k
lcw(i) = lc(i)
Next
End If
lc = Nothing '依次取汉字标题
lc = MgSplit(lColumnHeader)
If Not IsNothing(lc) Then
k = Math.Min(lc.Length, lch.Length) - 1
For i = 0 To k
lch(i) = lc(i)
Next
End If
For i = 0 To nLeng + lnewCols '先给初值
With bColumn(i)
.MapS = IIf(i = 0, bADDsm, IIf(i = 1, bADDid, IIf(i = 2, bADDtj, Nothing)))
.ReadOnlyB = True
.RedB = False
.WidthiAutoI = 0
.WidthI = 0
.HeaderS = IIf(i < lnewCols, "-", " ")
.TypeS = IIf(i = 0, "Boolean", IIf(i = 1, "Integer", IIf(i = 2, "Boolean", Nothing)))
End With
Next
lc = Nothing
lc = MgSplit(lColumnMap) '此时,lColumnMap肯定有值了
k = -1
''字段名、宽度、显示名这三个数组中,元素的个数,都以字段名的个数为准
For i = 0 To lc.Length - 1 '计算字段名数组中,在数据源中的字段数(可能有部分名称没在数据源中)
'去除重复的字段名称
s = Trim(UCase(lc(i)))
For n = i + 1 To lc.Length - 1
If s.Length > 0 And s = Trim(UCase(lc(n))) Then ' 如果字段名非空,并且与后面的都不相同
lc(n) = " "
End If
Next
If MFindField(Trim(lc(i))) >= 0 Then
If lc(i) = bADDid Or lc(i) = bADDtj Then '不计新加的字段
Else
k = k + 1
bColumn(k + lnewCols).MapS = lc(i)
bColumn(k + lnewCols).WidthI = CType(Val(lcw(i)), Integer)
bColumn(k + lnewCols).HeaderS = lch(i)
If k > nLeng Then
Exit For
End If
End If
End If
Next
For i = lnewCols To nLeng + lnewCols
k = bColumn(i).WidthI '如果有些宽度为负,或者没有赋值,则都将宽度设置为0
bColumn(i).WidthI = IIf(k < 0, 0, IIf(k > 400, 400, k))
s = bColumn(i).HeaderS
bColumn(i).HeaderS = IIf(s.Length < 1, " ", s)
Next
nLeng = nLeng + lnewCols
lc = Nothing '红色显示的字段名
lc = MgSplit(lMapRed)
If Not IsNothing(lc) Then
k = lc.Length - 1
k = Math.Min(k, nLeng)
For i = 0 To k '根据需要设置的红色字段的名称,在各列中查找,
For n = 2 To nLeng '如果找到,则把其值设置为 True
If bColumn(n).MapS = lc(i) Then
bColumn(n).RedB = True
Exit For
End If
Next
Next
Else '如果 红色字段名没有定义,则把所有的字段设置为 True
For n = lnewCols To nLeng
bColumn(n).RedB = True
Next
End If
lc = Nothing '只读字段名
lc = MgSplit(lMapOnly)
If Not IsNothing(lc) Then
k = lc.Length - 1
For i = 0 To k '在各列中查找,
For n = lnewCols To nLeng '如果找到,则把其值设置为 True
If bColumn(n).MapS = lc(i) Then
bColumn(n).ReadOnlyB = False
Exit For
End If
Next
Next
End If
Dim g As Graphics = Me.CreateGraphics
'计算每一列自动的宽度
For i = lnewCols To nLeng '记录数据源中,某字段中最多的字符数
s = bColumn(i).MapS
n = bColumn(i).HeaderS.Length '字段的标题,的字符数也参与比较
For Each r As DataRow In MyDataTable.Rows
If Not IsDBNull(r(s)) Then
n = Math.Max(n, Len(r(s).ToString))
End If
Next
n = IIf(n > 100, 100, n) '多于100个字符的,也只显示前100个字符,列宽了也不好看
'k = CInt(g.MeasureString(s, Me.Font).ToSize.Width) + 15
k = g.MeasureString(New String(CType("A", Char), n), Me.Font).Width + 15
bColumn(i).WidthiAutoI = IIf(bColumn(i).WidthI <= 0, 0, k)
Next
Dim ldc As DataColumn
Dim m As String '计算每列的数据类型,为方便计,只分五类
For i = lnewCols To nLeng
s = bColumn(i).MapS
m = UCase(MyDataTable.Columns(s).DataType.ToString)
Select Case m
Case UCase("System.Boolean")
m = "Boolean"
Case UCase("System.DateTime")
m = "DateTime"
Case UCase("System.Int16"), UCase("System.Int32"), UCase("System.Int64"), UCase("System.Byte")
m = "Integer"
Case UCase("System.Decimal"), UCase("System.Single"), UCase("System.Double")
m = "Decimal"
Case Else
m = "String"
End Select
bColumn(i).TypeS = m
Next
Catch ex As Exception
End Try
End Sub '初始化列数组
Private Sub Ma2AddColumn()Sub Ma2AddColumn() '加入两个新字段
Try
Dim lm1 As New DataColumn
Dim lm2 As New DataColumn
Dim lm3 As New DataColumn
With lm1 ' 我们会在自定义的排序操作期间使用此字段。
.ColumnName = bADDsm '为方便求和后排序而加的一列
.DataType = System.Type.GetType("System.Boolean")
.DefaultValue = Nothing
.ColumnMapping = System.Data.MappingType.Hidden
End With
With lm2
.ColumnName = bADDid '内部编号列
.DataType = GetType(Integer)
.AllowDBNull = True
End With
With lm3
.ColumnName = bADDtj '是否满足条件列
.DataType = GetType(System.Boolean)
.DefaultValue = False
.AllowDBNull = False
End With
Try
MyDataTable.Columns.Add(lm1)
MyDataTable.Columns.Add(lm2)
MyDataTable.Columns.Add(lm3)
'Call MaEditrow() '把两个字段的初值设置好...初始化时就不计算了,太慢,以后需要时才算
With lm2
.AutoIncrement = True
.AutoIncrementSeed = MyDataTable.Rows.Count + 100
.AutoIncrementStep = 1
End With
' 替 DataTable 对象建立一笔注脚资料列。可以不必写入新记录的值
' 仍然需要写新记录的值,因为,实际表的结构是有要求的。
Catch ex As Exception
End Try
MyDataTable.DataSet.EnforceConstraints = False
'MyDataTable.DataSet.f()
MyNewDataRow = MyDataTable.NewRow()
'lm1.ReadOnly = False
MyNewDataRow(bADDsm) = False
'lm1.ReadOnly = True
MyDataTable.Rows.Add(MyNewDataRow)
lNewRow = MyNewDataRow.ItemArray
Catch ex As Exception
End Try
End Sub '新字段:内部编号列,是否满足条件列
Private Sub Ma3setHead()Sub Ma3setHead()
Dim n, i, m As Integer '返回各个数组中最小的下标
Dim t As String
Dim fTS As New System.Windows.Forms.DataGridTableStyle
Dim fAbool As BqUgrdColumnBool
Dim fAtext As BqUgrdColumnText
Try
fTS.GridColumnStyles.Clear()
fTS.MappingName = MyDataTable.TableName
fTS.AllowSorting = False '这一句千万不能少,这样才能控制排序时不包括脚注行,即合计行
n = bColumn.Length - 1 '需要显示的字段个数
For i = 0 To n '新增加的列不显示
t = bColumn(i).TypeS
If t = "Boolean" Then
fAbool = New BqUgrdColumnBool(i)
AddHandler fAbool.BqmHandler, New bqeCellEventHandler(AddressOf SetEnableValues)
With fAbool
.HeaderText = bColumn(i).HeaderS
.MappingName = bColumn(i).MapS
.ReadOnly = bColumn(i).ReadOnlyB
.Width = bColumn(i).WidthI
.Alignment = HorizontalAlignment.Center '逻辑,居中
End With
fTS.GridColumnStyles.Add(fAbool)
Else
fAtext = New BqUgrdColumnText(i) '重绘所有的列
AddHandler fAtext.BqmHandler, New bqeCellEventHandler(AddressOf SetEnableValues)
With fAtext
.HeaderText = bColumn(i).HeaderS
.MappingName = bColumn(i).MapS
.ReadOnly = bColumn(i).ReadOnlyB
.Width = bColumn(i).WidthI
If t = "DateTime" Then '时间,左对齐
.TextBox.TextAlign = HorizontalAlignment.Left
.Alignment = HorizontalAlignment.Left
.Format = "yyyy-MM-dd hh:mm:ss"
ElseIf t = "Integer" Then '数字,整数
.TextBox.TextAlign = HorizontalAlignment.Right
.Alignment = HorizontalAlignment.Right
.Format = "###,###,###,###,###" '最好是不显示0或空值
ElseIf t = "Decimal" Then '数字,小数
.TextBox.TextAlign = HorizontalAlignment.Right
.Alignment = HorizontalAlignment.Right
.Format = "###,###,###,###,###,###.0000"
Else '其它文本
.TextBox.TextAlign = HorizontalAlignment.Left
.Alignment = HorizontalAlignment.Left
End If
End With
fTS.GridColumnStyles.Add(fAtext)
End If
If i < 3 Then
fTS.PreferredColumnWidth = 0
MyDataTable.Columns(bColumn(i).MapS).ColumnMapping = MappingType.Hidden
End If
Next
With Me
.TableStyles.Clear()
.TableStyles.Add(fTS)
.AllowSorting = False ' 停用 DataGrid 控制项的默认排序功能。
.CaptionVisible = IIf(MyDataTable.DataSet.Relations.Count > 0, True, False) '如果有关联,则显示标题
End With
Call MsRowHeaderWidth(15)
Catch ex As Exception
Dim kk As String
kk = ""
End Try
End Sub '显示中文标题
Private Sub Ma4Menu()Sub Ma4Menu()
ReDim sMenu(12)
sMenu(0) = "自动列宽"
sMenu(1) = "显示行编号"
sMenu(2) = "不显示Null"
sMenu(3) = "显示时间"
sMenu(4) = "整行选中"
sMenu(5) = "红字条件"
sMenu(6) = "统计与计算"
sMenu(7) = "合计"
sMenu(8) = "平均值"
sMenu(9) = "计数"
sMenu(10) = "最大值"
sMenu(11) = "最小值"
sMenu(12) = "-清除-统计内容"
Dim i As Integer
Dim m6 As MenuItem
oMenu.MenuItems.Clear()
For i = 0 To sMenu.Length - 1
Dim mi As New MenuItem
mi.Text = sMenu(i)
mi.Checked = False
mi.Enabled = True
AddHandler mi.Click, AddressOf mMenuClick '定义各个菜单的click事件
If i > 6 And i <= 12 Then
m6.MenuItems.Add(mi)
Else
oMenu.MenuItems.Add(mi)
End If
If i = 5 Then '第五个菜单,并且没有设置条件表达式,则不可选择
If lredConditiona.Length < 2 Then
mi.Enabled = False
End If
End If
If i = 6 Then
m6 = mi
End If
Next
Me.ContextMenu = oMenu
End Sub '定义菜单
Private Sub mMenuClick()Sub mMenuClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim s As String
Dim i As Boolean
Try
s = sender.text
i = IIf(sender.checked = True, True, False)
i = Not i
If s = sMenu(7) Or s = sMenu(8) Or s = sMenu(8) Or s = sMenu(9) Or s = sMenu(10) Or s = sMenu(11) Or s = sMenu(12) Then
Dim lm As MenuItem = sender
For Each lm In lm.Parent.MenuItems
lm.Checked = False
Next
'sender.checked = False
End If
Select Case s
Case sMenu(0)
'i = Not i
Me.BqpshowAutoWidths = i
Case sMenu(1)
'i = Not i
Me.BqpShowNumber = i
Case sMenu(2)
'i = Not i
Me.BqpShowNull = i
Case sMenu(3)
'i = Not i
Me.BqpShowTime = i
Case sMenu(4)
'i = Not i
Me.BqpshowAllColumnS = i
Case sMenu(5)
'i = Not i
Me.BqpshowRedConditiona = i
Case sMenu(7)
Me.Ma5setSum("Sum")
Case sMenu(8)
Me.Ma5setSum("avg")
Case sMenu(9)
Me.Ma5setSum("count")
Case sMenu(10)
Me.Ma5setSum("max")
Case sMenu(11)
Me.Ma5setSum("min")
Case sMenu(12)
Try
'MyDataTable.Columns(bADDsm).ReadOnly = False
MyNewDataRow.ItemArray = lNewRow
'MyDataTable.Columns(bADDsm).ReadOnly = True
Catch ex As Exception
End Try
End Select
sender.checked = i
Catch ex As Exception
End Try
End Sub
Private Sub Ma5setSum()Sub Ma5setSum(ByVal lType_Avg_Count_Max_Min_Sum As String)
Dim s, tj, js As String '聚和函数、条件、计算字段
Dim i, n As Integer
Dim m0 As String '每一次计算的结果
Dim k As String = Trim(UCase(lType_Avg_Count_Max_Min_Sum))
Select Case Trim(UCase(k))
Case "AVG" '列平均值
s = "Avg("
Case "COUNT" '列值的计数
s = "Count("
Case "MAX" '列中最大值 ,可针对文本
s = "Max("
Case "MIN" '列中最小值
s = "Min("
Case "SUM" '列值的合计
s = "Sum("
Case Else
s = "Sum("
End Select
Try
'MyDataTable.Columns(bADDsm).ReadOnly = False
MyNewDataRow.ItemArray = lNewRow
'MyDataTable.Columns(bADDsm).ReadOnly = True
Dim lCell As DataGridCell = New DataGridCell
lCell.RowNumber = MyDataTable.Rows.Count - 1
tj = bADDsm + " is null"
n = bColumn.Length - 1
For i = lnewCols To n
If k = "MAX" Or k = "MIN" Then '最大值,最小值,对所有的字段都求
Try
m0 = ""
js = s + bColumn(i).MapS + ")"
m0 = MyDataTable.Compute(js, tj).ToString
lCell.ColumnNumber = i
Me(lCell) = m0
Catch ex As Exception
End Try
Else
If (bColumn(i).TypeS = "Integer" Or bColumn(i).TypeS = "Decimal") Then
'对所有数值型数据
Try
m0 = ""
js = s + bColumn(i).MapS + ")"
m0 = MyDataTable.Compute(js, tj).ToString
lCell.ColumnNumber = i
Me(lCell) = m0
Catch ex As Exception
End Try
End If
End If
Next
Catch ex As Exception '遇到错误,从下一个开始继续
End Try
End Sub '设定注脚储存格的值。
Private Function MFindField()Function MFindField(ByVal sField As String) As Integer
'判断sField字段是否在表中,在则返回 -1
Dim i, m As Integer
m = -1
For i = 0 To MyDataTable.Columns.Count - 1
If UCase(sField) = UCase(MyDataTable.Columns(i).ColumnName) Then
m = i
Exit For
End If
Next
MFindField = m
End Function
Private Function MgSplit()Function MgSplit(ByVal s As String) As String()
'从指字符串中分离各个子串 ,分隔符用逗号
'参数:字符串,
Dim m0 As String() = Nothing
Dim m As String
Try
If Trim(s).Length > 0 Then
m = s.Replace(",", "") '除去逗号,以防止s全部都是逗号这种情况
If m.Length > 0 Then
m0 = s.Split(",")
End If
End If
Catch ex As Exception
End Try
Return m0
End Function '从指字符串中分离各个子串
Private Function MsRowHeaderWidth()Function MsRowHeaderWidth(ByVal Width As Integer)
If Me.TableStyles.Count = 0 Then
Me.RowHeaderWidth = Width
Else
Me.TableStyles(0).RowHeaderWidth = Width
End If
End Function '设置行标题的宽度
Private Sub MaEditrow()Sub MaEditrow()
Dim r As DataRow
Dim i As Integer = 0
Try '预防条件表达式设置不正确,
'If MFindField(bADDid) >= 0 Then
For Each r In MyDataTable.Rows
r(bADDid) = i
i = i + 1
Next
'End If
'If MFindField(bADDtj) >= 0 Then
If lredConditiona.Length > 1 Then '如果条件已经设置,则把满足条件的记录找出来
Dim rs() As DataRow
rs = MyDataTable.Select(lredConditiona) '找到满足条件的记录
For Each r In rs
r(bADDtj) = True 's2代表满足条件 列名
Next
End If
'End If
Catch ex As Exception
End Try
End Sub
Private Sub MsRowHeadr()Sub MsRowHeadr()
Dim g As System.Drawing.Graphics
'Dim iCount As Integer
Dim i, r, r1, r2, t, w As Integer
Dim m As String
Try
g = Me.CreateGraphics
i = MyDataView.Count
t = Me.GetCellBounds(0, 0).Top
r = CInt(t / ((Me.GetCellBounds(RowCount - 1, 0).Top - t + Me.GetCellBounds(0, 0).Height) / RowCount))
r = r - CInt(IIf(False, 1, IIf(Me.CaptionVisible = True, 2, 1)))
r1 = IIf(r < 0, -r, 0) '上面几行:得到可显示区域 第一行的行号
r = Me.VisibleRowCount
r = r1 + r
r2 = IIf(r < i, r, i) '得到可显示区域 最后一行的行号
w = CInt(g.MeasureString(r2.ToString, Me.Font).Width) + 15 '设置行标题的列宽
MsRowHeaderWidth(w)
w = r2.ToString.Length
For i = r1 To r2 - 1
t = Me.GetCellBounds(i, 0).Top + 2
m = "" & Trim(CStr(i + 1)) '留前置空格
m = IIf(m.Length = w, m, Space(w - m.Length) + m)
If i = RowCount - 1 Then
m = "汇总"
g.DrawString(m, Me.Font, New System.Drawing.SolidBrush(Me.ForeColor), 6, t)
Else
g.DrawString(m, Me.Font, New System.Drawing.SolidBrush(Me.ForeColor), 12, t)
End If
'12是x坐标,目的是需要留下左边当前记录标志(三角形)的位置
Next
Catch ex As Exception
Dim kk As String
kk = ""
End Try
End Sub '以下代码是在表格中最左边显示行号
Private Sub MsShowRed()Sub MsShowRed()
If lredConditiona.Length < 2 Then Exit Sub '如果没有设置条件,则不用设置
If lshowRedConditiona = True Then '需要分颜色显示满足条件的记录
Dim c As DataGridColumnStyle
Dim t As DataGridTableStyle
Dim i As Integer
Else
End If
End Sub
#End Region
Dim WithEvents lBM As System.Windows.Forms.BindingManagerBase
控件自身的事件和方法#Region " 控件自身的事件和方法 "
' 处理 DataTable 对象的 ColumnChanged 事件,
' 以便当储存格中的资料有所变动时能够加以追踪。
Private Sub MyDataTable_ColumnChanged()Sub MyDataTable_ColumnChanged(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles MyDataTable.ColumnChanged
Dim Row As Integer, Col As Integer
Row = 0
Col = 0
' 判断哪一个资料列内含资料变更的储存格。
Dim r As DataRow
For Each r In MyDataTable.Rows
If (r.Equals(e.Row)) Then
CurrentDataGridCellLocation.RowNumber = Row
CellValueChanged = True
Exit For
Row = Row + 1
End If
Next
' 判断哪一个资料行内含资料变更的储存格。
Dim lc As DataColumn
For Each lc In MyDataTable.Columns
If (lc.Equals(e.Column)) Then
CurrentDataGridCellLocation.ColumnNumber = Col
CellValueChanged = True
Exit For
Col = Col + 1
End If
Next
End Sub
' 处理 DataGrid 控制项的 CurrentCellChanged 事件。
Private Sub BqUDataGrid_CurrentCellChanged()Sub BqUDataGrid_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.CurrentCellChanged
If (CellValueChanged = True) Then
'---------------------需要再改一下,使得修改值后仍然回到原单元格
Call Ma5setSum("")
End If
CellValueChanged = False
RaiseEvent BqMSelectGrid() '调用自定义过程,让控件外部可以根据表格选择内容变化而变化
End Sub
' 处理 DataGrid 控制项的 MouseDown 事件以便实现自定义排序。
Private Sub BqUDataGrid_MouseDown()Sub BqUDataGrid_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
''还需要设置,不想让最后一行得到焦点
'''Dim myHitTest As DataGrid.HitTestInfo
'''myHitTest = Me.HitTest(e.X, e.Y)
'''Debug.WriteLine("Column " & myHitTest.Column)
'''Debug.WriteLine("Row " & myHitTest.Row)
'''Debug.WriteLine("Type " & myHitTest.Type)
'''Debug.WriteLine("ToString " & myHitTest.ToString)
'''Debug.WriteLine("Format " & myHitTest.Type.ToString)
'''Debug.WriteLine(RowCount.ToString)
'''If myHitTest.Type = DataGrid.HitTestType.Cell Then
''' Dim k1, k2 As Integer
''' k1 = myHitTest.Row
''' k2 = myHitTest.Column
''' If k1 = RowCount - 1 Then
''' Me.CurrentRowIndex = k1 - 1
''' End If
''' 'Dim ee As New bqeCellEventArgs(k1, k2) ' 使用作用资料列与作用资料行的编号来初始化事件指针。
''' 'RaiseEvent BqmHandler(Me, ee) ' 引发 bqmHandler 事件。
''' 'If Not ee.EnableValue Then ' 设定注脚资料列的前景色与背景色。
''' ' Me.CurrentRowIndex = k1 - 1
''' 'End If
'''End If
Dim lInfo As DataGrid.HitTestInfo
Dim m As String
lInfo = Me.HitTest(e.X, e.Y)
' 判断用户是否单击资料行标题。
If (lInfo.Type = DataGrid.HitTestType.ColumnHeader) And e.Button = MouseButtons.Left Then '只有左键才设置
Dim n As Integer = lInfo.Column
If (n <> -1) Then
' 执行自定义排序。要完成此项操作,请固定以递增顺序来排序 Boolean ▲△▼▽∧∨↑↓↖↗↘↙
' 资料型别字段,如此一来,注脚资料列才会显示在最下方。
Dim MyChar() As Char = {"▲"c, "▽"c}
'SortedColNum 表示上一次排序的位置,
With Me.TableStyles(0).GridColumnStyles(SortedColNum)
m = .HeaderText.Trim(MyChar).Trim() '要清除其上面的排序标志
.HeaderText = m
End With
m = bColumn(n).MapS
With Me.TableStyles(0).GridColumnStyles(n)
If (lynAscending = True) Then
MyDataView.Sort = bADDsm + " Asc," + m + " desc"
.HeaderText = "▲" + bColumn(n).HeaderS
Else
MyDataView.Sort = bADDsm + " Asc," + m + " asc"
.HeaderText = "▽" + bColumn(n).HeaderS
End If
lynAscending = Not lynAscending
SortedColNum = n
End With
End If
End If
End Sub
' 停用 DataGrid 控制项的注脚资料列。
Public Sub SetEnableValues()Sub SetEnableValues(ByVal sender As Object, ByVal e As bqeCellEventArgs)
If (e.Row = RowCount - 1) Then '表示最后一行,即脚注行
e.EnableValue = False
Else
e.EnableValue = True
End If
End Sub
' 完成整行选中状态的设置
Public Event BqmHandler As bqeCellEventHandler
Private Sub BqUDataGrid_MouseMove()Sub BqUDataGrid_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
If Me.CurrentRowIndex < 0 Then Exit Sub
If lAllColumns Then
Dim lhit As DataGrid.HitTestInfo
Dim t As DataGridTableStyle
For Each t In Me.TableStyles
t.SelectionBackColor = Me.SelectionBackColor
t.SelectionForeColor = Me.SelectionForeColor
t.ForeColor = Me.ForeColor
t.GridLineColor = Me.GridLineColor
Next
lhit = Me.HitTest(e.X, e.Y)
If lhit.Row <> -1 OrElse lhit.Column <> -1 Then
Me.Select(Me.CurrentRowIndex)
End If
End If
End Sub
Private Sub BqUDataGrid_Paint()Sub BqUDataGrid_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
If lshowNumber = True Then
MsRowHeadr()
End If
End Sub
#End Region
还需要完善的功能 写完后,复制到上面类中#Region "还需要完善的功能 写完后,复制到上面类中"
Public ReadOnly Property BqpKeyTag()Property BqpKeyTag(ByVal FieldName As String) As String
Get
Dim m0 As String = "-1"
Dim i As Integer
Try
i = MFindField(FieldName)
If i >= 0 Then
Dim rv As DataRowView = MyDataView.Item(lBM.Position)
m0 = rv.Row(FieldName).ToString
End If
Catch ex As Exception
End Try
Return m0
End Get
End Property '根据字段名返回其值
Public ReadOnly Property BqpRecornTJ()Property BqpRecornTJ() As Boolean '当前记录是否满足条件
Get
Dim m0 As Boolean = False
Try
If lFirst = True Then
Call Me.MaEditrow() ' 添加列后,还需要计算其它两列的数据
lFirst = False
End If
Dim rv As DataRowView = MyDataView.Item(lBM.Position)
m0 = rv.Row(bADDtj).ToString
Catch ex As Exception
End Try
Return m0
End Get
End Property '当前记录是否满足条件
Public ReadOnly Property BqpRConditionaRowS()Property BqpRConditionaRowS() As DataRow()
Get
Dim m0 As DataRow()
Try
If lFirst = True Then
Call Me.MaEditrow() ' 添加列后,还需要计算其它两列的数据
lFirst = False
End If
Dim s As String
s = bADDtj + " =True And " + bADDsm + " is null "
m0 = MyDataTable.Select(s)
Catch ex As Exception
End Try
Return m0
End Get
End Property '满足条件的记录集
'Public Sub BqMrowAdd(ByVal r As Array)
' 'Dim l As DataRow
' 'l = lSourceTb.NewRow()
' 'Dim i As Integer
' 'l.ItemArray = r
' 'lSourceTb.Rows.Add(r)
' ''lBMtb = New System.Windows.Forms.BindingManagerBase
' ''lBMtb = BindingContext(lSourceTb)
' ''i = lBMtb.Position
' ''lBMtb = CType(Me.BindingContext(Me.DataSource), CurrencyManager)
' ''lBMtb.Position = i
' 'Me.Refresh()
'End Sub '添加记录
'Public Sub BqMrowRemove(ByVal r As DataRow)
' 'lSourceTb.Rows.Remove(r)
' Me.Refresh()
'End Sub '移出记录
#End Region
End Class
#End Region
需要的其它自定义类#Region " 需要的其它自定义类"
' 声明一个委派给用于停用 DataGrid 控制项之储存格的事件使用。
Public Delegate Sub bqeCellEventHandler()Sub bqeCellEventHandler(ByVal sender As System.Object, ByVal e As bqeCellEventArgs)
' 定义一个衍生自 EventArgs 类别的事件指针类别 以便提供资料给 bqmHandler 事件。
Public Class bqeCellEventArgsClass bqeCellEventArgs
Inherits System.EventArgs
Dim lCol As Integer
Dim lRow As Integer
Dim lValue As Boolean
Public Sub New()Sub New(ByVal Row As Integer, ByVal Col As Integer)
lRow = Row
lCol = Col
lValue = True
End Sub
Public Property Column()Property Column() As Integer
Get
Return lCol
End Get
Set(ByVal Value As Integer)
lCol = Value
End Set
End Property
Public Property Row()Property Row() As Integer
Get
Return lRow
End Get
Set(ByVal Value As Integer)
lRow = Value
End Set
End Property
Public Property EnableValue()Property EnableValue() As Boolean
Get
Return lValue
End Get
Set(ByVal Value As Boolean)
lValue = Value
End Set
End Property
End Class
Public Class BqUgrdColumnTextClass BqUgrdColumnText
Inherits System.Windows.Forms.DataGridTextBoxColumn
' 替我们所定义的 bqeCellEventHandler 委派声明一个事件。
Public Event BqmHandler As bqeCellEventHandler
Private MyCol As Integer
' 储存 BqUgrdColumnText 控制项将被添加其中之资料行的资料行编号。
Public Sub New()Sub New(ByVal Column As Integer)
MyCol = Column
End Sub
' 覆写 Paint 方法以便设定注脚资料列的色彩。
Protected Overloads Overrides Sub Paint()Sub Paint(ByVal g As System.Drawing.Graphics, _
ByVal bounds As System.Drawing.Rectangle, _
ByVal source As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, _
ByVal backBrush As System.Drawing.Brush, _
ByVal foreBrush As System.Drawing.Brush, _
ByVal alignToRight As Boolean)
Dim e As New bqeCellEventArgs(rowNum, MyCol) ' 使用作用资料列与作用资料行的编号来初始化事件指针。
RaiseEvent BqmHandler(Me, e) ' 引发 bqmHandler 事件。
If Not e.EnableValue Then ' 设定注脚资料列的前景色与背景色。
If BqUDataGrid.BqColorFootBack Is Nothing Or BqUDataGrid.BqColorFootFont Is Nothing Then
backBrush = Brushes.DimGray ' Brushes.DarkSlateGray
foreBrush = Brushes.LightGreen
Else
backBrush = BqUDataGrid.BqColorFootBack
foreBrush = BqUDataGrid.BqColorFootFont
End If
End If
' 调用 DataGridTextBoxColumn 类别的 Paint 方法。
MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)
End Sub
' 覆写 Edit 方法以便停用注脚资料列。
Protected Overloads Overrides Sub Edit()Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal readOnlyFlag As Boolean, _
ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim e As bqeCellEventArgs = Nothing
e = New bqeCellEventArgs(rowNum, MyCol) ' 使用作用资料列与作用资料行的编号来初始化事件指针。
RaiseEvent BqmHandler(Me, e) ' 引发 bqmHandler 事件。
' 替除了注脚资料列以外的所有资料列调用 DataGridTextBoxColumn 类别的 Edit 方法。
If e.EnableValue Then
MyBase.Edit(source, rowNum, bounds, readOnlyFlag, instantText, cellIsVisible)
End If
End Sub
End Class '自定义的DataGridTextBoxColumn
Public Class BqUgrdColumnBoolClass BqUgrdColumnBool
Inherits System.Windows.Forms.DataGridBoolColumn
' 替我们所定义的 bqeCellEventHandler 委派声明一个事件。
Public Event BqmHandler As bqeCellEventHandler
Private MyCol As Integer
'' 储存 BqUgrdColumnText 控制项将被添加其中之资料行的资料行编号。
Public Sub New()Sub New(ByVal Column As Integer)
MyCol = Column
End Sub
' 覆写 Paint 方法以便设定注脚资料列的色彩。
Protected Overloads Overrides Sub Paint()Sub Paint(ByVal g As System.Drawing.Graphics, _
ByVal bounds As System.Drawing.Rectangle, _
ByVal source As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, _
ByVal backBrush As System.Drawing.Brush, _
ByVal foreBrush As System.Drawing.Brush, _
ByVal alignToRight As Boolean)
Dim e As New bqeCellEventArgs(rowNum, MyCol) ' 使用作用资料列与作用资料行的编号来初始化事件指针。
RaiseEvent BqmHandler(Me, e) ' 引发 bqmHandler 事件。
If Not e.EnableValue Then ' 设定注脚资料列的前景色与背景色。
If BqUDataGrid.BqColorFootBack Is Nothing _
Or BqUDataGrid.BqColorFootFont Is Nothing Then
backBrush = Brushes.DimGray ' Brushes.DarkSlateGray
foreBrush = Brushes.LightGreen
Else
backBrush = BqUDataGrid.BqColorFootBack
foreBrush = BqUDataGrid.BqColorFootFont
End If
End If
' 调用 DataGridTextBoxColumn 类别的 Paint 方法。
MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)
End Sub
' 覆写 Edit 方法以便停用注脚资料列。
Protected Overloads Overrides Sub Edit()Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal readOnlyFlag As Boolean, _
ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim e As bqeCellEventArgs = Nothing
e = New bqeCellEventArgs(rowNum, MyCol) ' 使用作用资料列与作用资料行的编号来初始化事件指针。
RaiseEvent BqmHandler(Me, e) ' 引发 bqmHandler 事件。
' 替除了注脚资料列以外的所有资料列调用 DataGridTextBoxColumn 类别的 Edit 方法。
If e.EnableValue Then
MyBase.Edit(source, rowNum, bounds, readOnlyFlag, instantText, cellIsVisible)
End If
End Sub
End Class '自定义的DataGridBoolColumn
#End Region