Henry手记:WinForm Datagrid结构剖析(二)

** Henry ** ** 手记 — WinForm Datagrid ** ** 结构剖析(二) **

韩睿 ( 2002-12-5 )

继 上一篇 发表已有数日了,实在是因为太忙,无暇写继篇。却不断收到网友的鼓励与询问,不得不忘却近日的疲惫,匆匆上阵,希望不会让大家太失望。

** 二、自定义功能 ** ** **

上一节讲的是 Datagrid 的基本结构,对于一般的问题应付起来已经是够了,但遇上一些特别的需求,比如说想让一个 cell 变色,想在 Datagrid 中加入一个自定义的控件列(比如 ComboBox ),就需要对上节的内容进行活用了。今天我们先来谈谈如何将某个 cell ,或某行的前景与背景色进行变化,借以让大家熟练掌握到 Datagrid 的操作。

图1

图 1 变色示例图

在图 1 中,我使三个 cell 的前景与背景色都发生了变化,但它们的激发机制是不一样的,“美国”、“中国”两个 cell 我是用指定 cell 位置的方式使其变色的,而“ 3 ”这个 cell 是我在数据源中进行判断找到大于 2 的那个 cell 并使其变色,从而得到的。下文将对它们进行详述。

1. cell 的屏显工作步骤

在第一节中,我给大家展示了 Datagrid 的结构,其中提到, Datagrid 中是由 DataGridTableStyle 来决定它的外观, DataGridTableStyle 是由 DataGridColumnStyle 来组成的,默认的 DataGridColumnStyle 就是一个文本框列,背景色为白,前景色为黑色,这就是我们面前的作料了。我们就要想办法进行调整,调整的另一个前提就是工续了 , 它到底支不支持对 cell 的调色呢?

还记得我在上节列出的代码吗?(如果不记得,请打开原文对照着看一下),我在重绘 Datagrid 以获得列头、列宽的改变时,用的是:

Dim aColumnTextColumn As DataGridTextBoxColumn '决定每一列的样式

它就是我所说的默认列样式了。想要进行改变其外观的整容手术,就不得不进行外科手术了。请戴上手套,执起快刀,我 们开始解剖 DataGridTextBoxColumn 类了。

该类的作用就是: DataGridColumnStyle _ 的单元格中承载 _ TextBox 控件以便编辑字符串。

我们在第一节中使用的是其几个属性: HeadText 和 MappingName 等等。它们都是对现有类的应用,对我们今天的工作没有太大帮助。我们今天要看看该类是如何能显示出用户输入或载入的文字的。这就必须了解其“受保护的方法”的工作了。

在您更改了 DataGridTextBoxColumn 类的一个实例 aColumnTextColumn 的属性后,会使用下面这句:

ts.GridColumnStyles.Add(aColumnTextColumn) 来向Datagrid的TableStyle(ts)中的GridColumnStyle添加一个aColumnTextColumn,继而可以使用 DataGridTextBoxColumn 类的属性与方法。

而显示的步骤无非是如下四步:

a. 获得要显示于 Datagrid 中的位置

b. 获得要显示在该位置上的数据

c. 获得要显示时使用的 Textbox 的属性

d. 开始向屏幕绘图

前两步无可厚非,我们不需要改变什么,在该类中,如果 Datagrid 与某数据源进行了绑定,是使用 GetColumnValueAtRow 方法来从指定的数据源的指定位置取出数据,(在 Datagrid 中的数据被用户实时编辑发生更改后,用 SetColumnValueAtRow 方法向数据源回传值,用以保持数据的同步)。如果是用户实时的输入数据,则使用 Edit 方法将实时的数据传递到 cell 中去。

然后调用 Paint 方法记录绘制列的参数,最后通过 PaintText 去进行列中的 cell 的绘制。这里稍说明一下, Paint 是受系统自动控制与调用的,在 Datagrid 显示在屏幕的过程中当 Datagrid 外观发生外部的变化时(比如被另一个窗体遮盖后又移开),会自动调用运行,用以维护其外观。

看,并不复杂嘛,那我们如何进行改变呢?当然是想办法在 Paint 与 PaintText 进行交互的时候加入我们自己的代码,来个“狸猫换太子”。

2. 变更工作思路

所以我们要做的工作就相应成为:

a. 重载 Paint 方法

b. 实现 Paint 要完成的工作,包括获得要显示的字符, textbox 的属性(这就是工作的重点)

c. 向 PaintText 传送工作参数,并激发其进行工作。

那么工作的步骤就倒过来考虑,首先看一下要能在屏幕上绘图, PaintText 到底需要什么参数呢?

PaintText 方法有两种定义方式:

A. 在 给定位置处依据指定的对齐方式绘制文本和边框。

Overloads Protected Sub PaintText(Graphics, Rectangle, String, Boolean)

B. 在指定位置用指定的颜色和对齐方式绘制文本和边框。

Overloads Protected Sub PaintText(Graphics, Rectangle, String, Brush, Brush, Boolean)

我们要做的工作是要改变文本框的配色方案,当然是要用 B 的定义方法喽,其详细的解释为:

Overloads Protected Sub PaintText( _

ByVal g As Graphics, _

ByVal textBounds As Rectangle, _

ByVal text As String, _

ByVal backBrush As Brush, _

ByVal foreBrush As Brush, _

ByVal alignToRight As Boolean _

)

** 参数 ** ** **

g :一个 Graphics 对象,它用于绘制字符串。

textBounds :一个 Rectangle ,它包含矩形的边界数据。

text :要绘制到屏幕上的字符串。

BackBrush :一个 Brush ,它确定矩形的 背景色

foreBrush :一个 Brush ,它确定矩形的 前景色 。

AlignToRight :指示文本是否为右对齐的值。

看,我们需要的属性:背景色与前景色就这么展现出来了!那么我们在 Paint 中定义好指定 cell 的前景与背景色,传递给它不就 OK 了吗?

Paint 也有三种定义方式,与上述 PaintText 相对应的定义方式为:

Overrides Overloads Protected Friend Sub Paint( _

ByVal g As Graphics, _

ByVal bounds As Rectangle, _

ByVal source As CurrencyManager, _

ByVal rowNum As Integer, _

ByVal backBrush As Brush, _

ByVal foreBrush As Brush, _

ByVal alignToRight As Boolean _

)

如上文所述, Paint 是自动由系统控制运行的,因此,它会不断地完成一些必要的工作,如读取数据,定义 PaintText 的参数。如上定义,与 PaintText 的参数不同之处在于多了两个参数: source 和 rowNum 。它们是干什么的?还记得我在上文中所说屏显 cell 的前两步工作吗? source 就表示数据源, rowNum 标志了 cell 在 Datagrid 中的位置。等等, Datagrid 中的 cell 的位置应该是由行与列两个变量决定的呀,为什么在这里只有一个变量呢?

这就是 Paint 自身的工作机制问题了,我在上面介绍 paint 时说“ Paint 方法记录绘制列的参数”,意思是说,系统是调用 Paint 来画列的!所以系统会自动控制 Paint 从第一列向最后一列进行递增,做为 Paint 自身,当然只要记录下行号就可以控制 cell 了!这也就是我们能得以改变 cell 外观的 真正道理

我们调用 GetColumnValueAtRow ( source,rowNow )就可以借助系统递增列号的功能从 source 中读取数据,然后逐 cell 赋值了。

有一个好玩的事情,我控制了刷新的屏显过程后,发现系统绘图其实并不是一列一列画的,而是一行一行画的。这是为什么呢?其实这与我们上文分析的并不冲突。这与屏幕的显示刷新方式有关,实际上系统是按列将数据储存进缓存,然后按行向外显示的!这一点说明是给一些喜欢深究的朋友提个醒。见图 2 所示:

图2

图 2 刷新过程演示

实现代码与处理技巧见:“WinForm Datagrid结构剖析(二)程序” 一文。

经过本文的论述,希望您已经掌握了 Datagrid 的一部分实现秘密!下一篇我将带给大家更全面的资讯,不再是满足于对一个类的改造,而是自定义一个列样式类。请给予笔者更多的鼓励与批评指正。下次见!

----

声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。

QQ: 18349592

E-Mail: [email protected]

请访问本人专栏: http://www.csdn.net/develop/author/netauthor/Latitude/

Published At
Categories with Web编程
Tagged with
comments powered by Disqus