excel表格数字前面的红色绿色圆圈怎么去掉??

免责声明:酷知网所有文字、图片、视频、音频等资料均来自互联网,不代表本站赞同其观点,内容仅代表作者本人意见,若因此产生任何纠纷作者本人负责,本站亦不为其版权负责! 如有问题,请联系我们

在 Delphi 语言的数据库编程中,DBGrid 是显示数据的主要手段之一。但是 DBGrid 缺省的外观未免显得单调和缺乏创意。其实,我们完全可以在我们的程序中通过编程来达到美化DBGrid 外观的目的。通过编程,我们可以改变 DBGrid 的表头、网格、网格线的前景色和背景色,以及相关的字体的大小和风格。
    以下的示例程序演示了对 DBGrid 各属性的设置,使 Delphi 显示的表格就像网页中的表格一样漂亮美观。

  11:26:02    自制精美易用的DBGrid【陈大峰】   看了以上这么多的技巧和方法,想必大家未免会有一种冲动吧-自己动手做一个DBGrid,下面就介绍一种自制DBGrid的方法啦。

    Delphi中的TDBGrid是一个使用频率很高的VCL元件。TDBGrid有许多优良的特性,例如它是数据绑定的,能够定义功能强大的永久字段,事件丰富等,特别是使用非常简单。但是,与FoxPro、VB 、PB中的DBGrid相比就会发现,TDBGrid也有明显的缺陷:它的键盘操作方式非常怪异难用。虽然很多人都通过编程把回车键转换成Tab键来改进TDBGrid的输入方式,但是仍然不能很好地解决问题,这是为什么呢?本文将对造成这种缺陷的根本原因进行分析,并在此基础上制作一个输入极其简便、界面风格类似Excel的DBGridPro元件。

     DBGrid的格子(Cell)有四种状态:输入状态(有输入光标,可以输入,记作状态A1);下拉状态(弹出了下拉列表,可以选择,记作状态A2);高亮度状态(没有输入光标,可以输入,记作状态B);显示状态(不能输入,记作状态C)。DBGrid接受的控制键有回车,Tab,Esc,以及方向键。据此可以画出每个Cell的状态转换图:

    不难看出,当用户移动输入焦点时,对不同的移动方向要用不同的操作方法,甚至可能必须使用多个不同的键或借助鼠标来完成一个操作。当有下拉列表和要斜向移动的时候这种问题尤为明显。因此,输入困难的根本原因是其状态图过于复杂和不一致。基于这种认识,我们可以对DBGrid作三点改造:

改造1:显然B状态是毫无意义的,应该去掉。这意味着焦点每进入一个新的Cell,就立即进入编辑状态,而不要再按回车了。每个进入状态B的Cell都需要重新绘制,因此我们可以在绘制动作中判断是否有状态为gdFocused的Cell,若有则设置EditorMode为真。值得注意的是,TDBGrid用来画Cell的函数DefaultDrawColumnCell并不是虚函数,因此不能通过继承改变其行为,而只能使用其提供的事件OnDrawColumnCell来插入一些动作。在DBGridPro中,这一点是通过实现显示事件OnDrawColumnCell来实现的。但是这样一来,外部对象就不能使用该事件了,所以提供了一个OnOwnDrawColumnCell事件来替代它。见代码中的Create和DefaultDrawColumnCell函数。

改造2:控制键应该简化,尽量增加每个控制键的能力。在DBGridPro中,强化了方向键和回车键的功能:当光标在行末行首位置时,按方向键就能跳格;回车能横向移动输入焦点,并且还能弹出下拉列表(见改造3)。在实现方法上,可以利用键盘事件API(keybd_event)来将控制键转换成TDBGrid的控制键(如在编辑状态中回车,则取消该事件并重新发出一个Tab键事件)。当监测到左右方向键时,通过向编辑框发送EM_CHARFROMPOS消息判断编辑框中的光标位置,以决定是否应该跳格。见代码中的DoKeyUped函数。

改造3:简化下拉类型Cell的输入方式。在DBGridPro中,用户可以用回车来弹出下拉列表。这种方式看起来可能会造成的回车功能的混淆,但是只要处理得当,用户会觉得非常方便:当进入下拉类型的Cell之后,如果用户直接键入修改,则按回车进入下一格;否则弹出下拉列表,选择之后再按回车时关闭下拉列表并立即进入下一格。见代码中的DoKeyUped函数和DefaultDrawColumnCell函数。

    一番改造之后,用户输入已经非常方便了,但是又带来了新的问题:在TDBGrid中,用户可以通过高亮度的Cell很快知道焦点在哪里,而DBGridPro中根本不会出现这种Cell,所以用户可能很难发现输入焦点!一种理想的方法是像Excel一样在焦点位置处放一个黑框--这一点是可以实现的(如图2)。

    Windows中提供了一组API,用于在窗口上建立可接受鼠标点击事件的区域(Region)。多个Region可以以不同的方式组合起来,从而得到"异型"窗口,包括空心窗口。DBGridPro就利用了这个功能。它在内部建立了一个黑色的Panel,然后在上面设置空心的Region,并把它"套"在有输入焦点的Cell上,这样用户就能看到一个醒目的边框了。

好事多磨,现在又出现了新的问题:当Column位置或宽度改变时,其边框必须同步变化。仅利用鼠标事件显然不能完全解决这个问题,因为在程序中也可以设置Column的宽度;用事件OnDrawColumnCell也不能解决(宽度改变时并不触发该事件)。幸运的是,TDBGrid中的输入框实际上是一个浮动在它上面的TDBGridInplaceEdit(继承自TInplaceEdit),如果我们能监测到TDBGridInplaceEdit在什么时候改变大小和位置,就可以让边框也跟着改变了。要实现这一点,用一个从TDBGridInplaceEdit继承的、处理了WM_WINDOWPOSCHANGED消息的子类来替换原来的TDBGridInplaceEdit将是最简单的办法。通过查看源代码发现,输入框由CreateEditor函数创建的,而这是个虚函数--这表明TDBGrid愿意让子类来创建输入框,只要它是从TInplaceEdit类型的。从设计模式的角度来看,这种设计方法被称为"工厂方法"(Factory Method),它使一个类的实例化延迟到其子类。看来现在我们的目的就要达到了。

不幸的是,TDBGridInplaceEdit在DBGrids.pas中定义在implement中(这样外部文件就无法看到其定义了),因此除非把它的代码全部拷贝一遍,或者直接修改DBGrids.pas文件(显然这前者不可取;后者又会带来版本兼容性问题),我们是不能从TDBGridInplaceEdit继承的。难道就没有好办法了吗?当然还有:我们可以利用TDBGridInplaceEdit的可读写属性WindowProc来捕获WM_WINDOWPOSCHANGED消息。WindowProc实际上是一个函数指针,它指向的函数用来处理发到该窗口元件的所有消息。于是,我们可以在CreateEditor中将创建出的TDBGridInplaceEdit的WndProc替换成我们自己实现的勾挂函数的指针,从而实现和类继承相同的功能。这样做的缺点是破坏了类的封装性,因为我们不得不在DBGridPro中处理属于TDBGridInplaceEdit的工作。当然,可能还有其他更好的方法,欢迎读者提出建议。

    至此,TDBGrid已经被改造成一个操作方便、界面美观的DBGridPro了,我们可以把它注册成VCL元件使用。以下是它的源代码:

  Delphi中向TDBGrid添加组件是一件十分麻烦的事情。笔者在这里向大家介绍一种利用WIN32 API函数在TDBGRID中嵌入CHECKBOX组件的方法。

  TDBGrid部件是用于显示和编辑数据库表中记录信息的重要部件,它是我们在程序设计过程中要经常使用的一个强有力的工具。TDBGrid具有很多重要的属性,我们可以在程序设计阶段和程序运行过程中进行设置。TDBGrid部件中有很多重要的属性,我们在这里重点介绍Option属性和DefaultDrawing属性,其他属性及其设置方法请参看联机帮助文件。

  Options属性:它是TDBGrid部件的一个扩展属性,在程序设计阶段设置Options属性可以控制TDBGrid部件的显示特性和对事件的响应特性。

  DefalultDrawing属性:该属性是布尔型属性,它用于控制网格中各网格单元的绘制方式。在缺省情况下,该属性的值为True,也就是说Delphi使用网格本身缺省的方法绘制网格中各网格单元,并填充各网格单元中的内容,各网格单元中的数据根据其对应的字段部件的DisplayFormat属性和EidtFormat属性进行显示和绘制。如果DefaulDrawing属性被设置为False,Delphi不会自动地绘制网格中各网格单元和网格单元中的数据,用户必须自己为TDBGrid部件的OnDrawDataCell事件编写相应的程序以用于绘制各网格单元和其中的数据。

  需要注意的是,当一个布尔字段得到焦点时,TDBGrid.Options中的 gdEditing属性不能被设置成为可编辑模式。另外,TDBGrid.DefaultDrawing属性不要设置为FALSE,否则,就不能得到网格中画布属性的句柄。

  程序设计开始时就应考虑:需要设定一变量来存储原始的 TDBGrid.Options的所有属性值。这样,当一boolean字段所在栏得到焦点时将要关闭TDBGrid.Options中gdEditing的可编辑模式。与此相对应,若该栏失去焦点时,就要重新恢复原始的 TDBGrid.Options的所有属性值。

  在实例中可以通过鼠标点击或敲打空格键改变布尔值,这样就需要触发TDBGrid.OnCellClick事件和TDBGrid.OnKeyDown事件。因为这两个事件都是改变单元格中逻辑字段的布尔值,所以为了减少代码的重复最好创建一个私有过程(SaveBoolean;)来完成逻辑值的输入,以后,在不同的事件中调用此过程即可。

  对 TDBGrid.OnDrawColumnCell事件的处理是整个程序的关键。处理嵌入组件的显示的传统方法是:在表单上实际添加组件对象,然后对组件的位置属性与网格中单元格的位置属性进行调整,以达到嵌入的视觉效果。这种方法虽然可行但代码量大,实际运行时控制性很差。笔者采用的方法是充分利用WIN32

  在TDBGrid.OnDrawColumnCell事件中,我想大家会注意到:设定一个整型数组常数,而这个返回的整数值是与布尔值相一致的,如果字段是逻辑字段,则只将其布尔值放入数组中,提供给DrawFrameControl()函数中的状态参数进行调用,从而实现了Checkbox组件在网格中的嵌入效果。

我要回帖

更多关于 excel表格带格式复制 的文章

 

随机推荐