3. 代码实现
WinForm Datagrid结构剖析(二)一文中说了这么多,最后还是要落于实践。解决方法何在?简而言之,就是创建一个能完成 DataGridTextBoxColumn类的大部分功能,但扩展了cell色彩控制功能的新类,怎么创建,当然是继承喽:
该类的主要作用除了上文所说的重载 Paint外,最主要的目标在于如何将用户的要求(cell的位置,cell的背景色、前景色)保存下来,在绘制textbox的时候传递进Paint函数中去。实现的方法是用三个集合:一个用于记录行号(不记录列号的原因是由于绘制是按列的ColumnStyle保存的,自动保存了列号),一个用于记录背景色,一个用于记录前景色。请读者自行阅读代码,如果有什么问题,可以写在下方的意见中,或直接发信给 我 。
文件名: CdatagridColor.vb
类名: DataGridColoredTextBoxColumn
------------X从此开始X----------------------------
Imports System.Windows.Forms
Public Class DataGridColoredTextBoxColumn
Inherits DataGridTextBoxColumn ‘ 继承接口
Public rowcollection As New Collection() '用于存放行号的集合
Public BackColor() As Color '用于存放背景色的集合,索引与行号集号一致(集合索引减1)
Public ForeColor() As Color '用于存放前景色的集合,索引与行号集号一致
Private Function GetText( ByVal Value As Object ) As String
'为进行重绘读出textbox中的内容,这个函数是增加容错能力的,与实现机制无关
If TypeOf (Value) Is System.DBNull Then
Return NullText
ElseIf Value Is Nothing Then
Return ""
Else
Return Value.ToString
End If
End Function
Protected Overloads Overrides 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 text As String
'按默认模式重绘
text = GetText(GetColumnValueAtRow(source, rowNum)) ‘这句就是上文提及的取数据
backBrush = New SolidBrush(TextBox.BackColor) ‘背景色
foreBrush = New SolidBrush(TextBox.ForeColor) ‘前景色
'防止用户没有定义集合大小
ReDim Preserve BackColor(rowcollection.Count)
ReDim Preserve ForeColor(rowcollection.Count)
Dim i As Integer = 1 '集合索引从1开始
Do While (i <= rowcollection.Count)
If rowNum = Val(rowcollection.Item(i)) Then ‘判断要集合中的行数是
If Not BackColor(i - 1).IsEmpty Then '没有定义的就按默认色绘制
backBrush = New SolidBrush(BackColor(i - 1))
End If
If Not ForeColor(i - 1).IsEmpty Then '没有定义的就按默认色绘制
foreBrush = New SolidBrush(ForeColor(i - 1))
End If
End If
i += 1
Loop
MyBase .PaintText(g, bounds, text, backBrush, foreBrush, alignToRight)
End Sub
End Class
--------------------X类到此结束X---------------------------------
下面是我的例子中“变色”按键( ID:button2)的代码。实现了两种变色方式:指定位置变色,根据数据源条件判断结果来动态变色:
-------------------X代码X-----------------------------------------
Private Sub Button2_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button2.Click
Dim dt As DataTable
Dim ts As New DataGridTableStyle()
Dim aColumnTextColumn As DataGridColoredTextBoxColumn '上面自定义的类
dt = DataSet11.Tables("table") ‘ Dataset11请自已去定义,或者看一下我的 前一篇文章
DataGrid1.DataSource = dt ‘ 数据源绑定
ts.MappingName = dt.TableName
Dim numCols As Integer
numCols = DataSet11.Tables("table").Columns.Count ‘ 统计列数
Dim i, j As Integer
i = 0
j = 0
Do While (i < numCols) '重绘所有的列
aColumnTextColumn = New DataGridColoredTextBoxColumn()
If i = 0 Then
aColumnTextColumn.rowcollection.Add(0) ‘ 指定行数
aColumnTextColumn.rowcollection.Add(2)
ReDim aColumnTextColumn.ForeColor(aColumnTextColumn.rowcollection.Count)
ReDim aColumnTextColumn.BackColor(aColumnTextColumn.rowcollection.Count)
'不赋值就是默认色,背景为白,前景为黑
aColumnTextColumn.ForeColor(0) = Color.Red
aColumnTextColumn.ForeColor(1) = Color.Blue
aColumnTextColumn.BackColor(0) = Color.Pink
aColumnTextColumn.BackColor(1) = Color.Aqua
End If
If i = 1 Then
For j = 0 To DataSet11.Tables("table").Rows.Count - 1
If DataSet11.Tables("table").Rows(j)(i) > 2 Then ‘ 判断列中哪一个 cell会大于2
aColumnTextColumn.rowcollection.Add(j)
ReDim ColumnTextColumn.ForeColor(aColumnTextColumn.rowcollection.Count)
ReDim aColumnTextColumn.BackColor(aColumnTextColumn.rowcollection.Count)
aColumnTextColumn.ForeColor(0) = Color.White
aColumnTextColumn.BackColor(0) = Color.Black
End If
Next
End If
'要更改列头名,请改下句的HeaderText值
aColumnTextColumn.HeaderText = DataSet11.Tables("table").Columns(i).ColumnName
aColumnTextColumn.MappingName = DataSet11.Tables("table").Columns(i).ColumnName
ts.GridColumnStyles.Add(aColumnTextColumn)
i = (i + 1)
Loop
DataGrid1.TableStyles.Add(ts)
End Sub
这里说明一点,判断时要注意类型的一致,在本例中,第二列的类型是数字型的,所以直接与数字 2 进行比对大小。
祝福您, 下次见!
----
声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。
QQ: 18349592
E-Mail: [email protected]
请访问本人专栏: http://www.csdn.net/develop/author/netauthor/Latitude/