如何在DBGrid中选中行,而又让它可以进入编辑状态?
  也许你会问我这有什么用?呵呵,做数据库应用的兄弟们会深有感触,当用DBGrid显示的字段过多时,用户不得不拉动最下面的滚动条,去看最右边的东西,如果没有设置DBGrid->Options[dgRowSelect],那么,拉到最右边之后,很有可能看串行的;如果设置了DBGrid->Options[dgRowSelect],则在拉到最右边之后,不会看串行,但是鼠标点击其它行(不是当前选中行)时,DBGrid的视图一下子就会回到显示最左边的那一列,确实很麻烦,用户不得不一次又一次的拖运下面的滚动条。
  一同事因这个问题而苦恼,而我又在CSDN的文档库中看到了这篇文章:
  《DBGrid使用全书(五)》,链接:http://dev.csdn.net/article/51/51845.shtm,是Delphi版本的,核心代码如下:
  type
   TMyDBGrid=class(TDBGrid);
  //DBGrid1.Options->dgEditing=True
  //DBGrid1.Options->dgRowSelect=False
  procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
   DataCol: Integer; Column: TColumn; State: TGridDrawState);
  begin
   with TMyDBGrid(Sender) do
   begin
     if DataLink.ActiveRecord=Row-1 then
     begin
       Canvas.Font.Color:=clWhite;
       Canvas.Brush.Color:=$00800040;
     end
     else
     begin
       Canvas.Brush.Color:=Color;
       Canvas.Font.Color:=Font.Color;
     end;
     DefaultDrawColumnCell(Rect,DataCol,Column,State);
   end;
  end; 
  他的解决办法是:曲线救国,取消DBGrid->Options[dgRowSelect],把当前选中行的背景绘制成蓝色,就象是被选中一样,想法确实很妙。我们公司使用C++Builder,我只好把这段代码改为C++Builder版本的,这时,我才发现这段代码的精妙之处。
  我发现DataLink属性是TCustomDBGrid中声明为protected的,而在DBGrid中并未声明它的可见性,因此,不能直接使用它;而Row属性则是在TCustomGrid中声明为protected的,在TCustomGrid的子类中也未声明它的可见性,那么,这段代码为何在Delphi中运行的很好?
  原因就在于:ObjectPascal的单元封装,在同一个单元中定义的类,互相之间是友员的关系,我们再来看这段代码的开头:
  type
   TMyDBGrid = class(TDBGrid);
  声明了一个TMyDBGrid类,那么,当前这个窗体类就和TMyDBGird类互为友元了,那么当然当前窗体类可以直接访问TMyDBGrid的私有属性Row和DataLink了,一切都明了了,那么用C++就好实现了,核心代码如下:
  void __fastcall TMainForm::LineSelEdit(TObject *Sender,const TRect &Rect, int DataCol, TColumn *Column,TGridDrawState State)
// 本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=637&d=2724wn
  {
      class TMyGridBase : public TCustomGrid
      {
      public:
          __property Row;
      };
      class TMyGrid : public TCustomDBGrid
      {
      public:
          __property DataLink;
      };
      TMyGrid *MyGrid = (TMyGrid*)Sender;
      TMyGridBase *MyGridBase = (TMyGridBase*)Sender;
      TDBGrid *Grid = (TDBGrid*)Sender;
  
      if(MyGrid->DataLink->ActiveRecord == MyGridBase->Row-1) {
          Grid->Canvas->Font->Color = clWhite;
          Grid->Canvas->Brush->Color = TColor(0x00800040);
      } else {
          Grid->Canvas->Brush->Color = Grid->Color;
          Grid->Canvas->Font->Color = Grid->Font->Color;
      }
  
      Grid->DefaultDrawColumnCell(Rect,DataCol,Column,State);
  }
  我把它封装成一个函数,函数的参数与DBGrid的OnDrawDataCell的参数一样,使用它的方法就是取消设置DBGrid->Options[dgRowSelect],然后设置DBGrid->DefaultDrawing = false,然后在这个DBGrid的OnDrawDataCell事件中调用这个函数,如下:
  void __fastcall TMainForm::DBGridDrawColumnCell(TObject *Sender,
        const TRect &Rect, int DataCol, TColumn *Column,
        TGridDrawState State)
  {
      this->LineSelEdit(Sender,Rect,DataCol,Column,State);
  }
原文链接:http://www.ccrun.com/article.asp?i=637&d=2724wn

在DBGrid中可选中行而又可进入编辑状态的更多相关文章

  1. Lazarus的DBGrid中回车键的处理

    Lazarus的DBGrid中回车键默认行为是向下移动一个记录,如果想对这一事件做处理,请不要在onkeypress里处理,而在onkeydown事件里处理.

  2. (很难啊)如何实时获取DBGrid 中当前单元格输入的内容? [问题点数:100分,结帖人yifawu100]

    如何获取DBGrid 中当前单元格输入的内容? 还没输入完成,我想实时获取 Cell中的内容,以便作其他处理,用什么事件呢? 所以Field的Onchange事件是没用的. DBGrid1.Selec ...

  3. 在dbgrid中如何多行选中记录(ctl与shift均可用)

    在dbgrid中如何多行选中记录(ctl与shift均可用),设置dbgrid的dgmultiselect为true,只有ctl好用而shift不好用,如何使shift也好用 Dbgrid源代码:pr ...

  4. 如何取得dbgrid中未保存(post)的值(50分)

    比如说处在编辑状态时,想取得当前记录值 Dataset.fields[0].Value 就是当前值:Dataset.fields[0].OldValue 就是原始值. 呵呵,我指得是在编辑时,就是按键 ...

  5. 如何实时获取DBGrid 中当前单元格输入的内容?

    如何获取DBGrid 中当前单元格输入的内容? 还没输入完成,我想实时获取 Cell中的内容,以便作其他处理, 用什么事件呢? 所以Field的Onchange事件是没用的. 这个问题简单啊,每输入1 ...

  6. ASP.net中GridView中增加一行记录并默认显示为编辑状态

    //添加 protected void Button1_Click(object sender, EventArgs e) { DataSet ds = (DataSet)pa.GetDataSet( ...

  7. ubuntu中vi在编辑状态下方向键不能用的解决

    ubuntu中vi在编辑状态下方向键不能用,还有回格键不能删除等,我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令. 安装 ...

  8. 在系统启动时,Windows Vista 中、 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TIME_WAIT 状态的所有 TCP/IP 端口

    在系统启动时,Windows Vista 中. 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TI ...

  9. TFS中设置任务中的“计划开始时间”为可编辑状态

    问题现象 如果使用TFS系统的默认模板CMMI新建团队项目,你会发现在网页浏览器中,任务工作项的"计划开始日期"和"计划结束日期"的类型是普通字符,并且不能修改 ...

随机推荐

  1. gmtime与mktime的重新编写

    这几日发现Linux的mktime与gmtime所处理的数据类型是32位的,即代表时间设置只能设置到2038年,在公司的产品要实现这个时间的突破还是得自己写一个新的处理时间的函数. 作为一个刚毕业的程 ...

  2. C#LINQ集合操作

    LINQ的集合运算 List<int> lstOne = new List<int>() { 1, 55, 223, 25 }; List<int> lstTwo ...

  3. Prism for WPF 搭建一个简单的模块化开发框架(三) 给TreeView加样式做成菜单

    原文:Prism for WPF 搭建一个简单的模块化开发框架(三) 给TreeView加样式做成菜单 昨天晚上把TreeView的样式做了一下,今天给TreeView绑了数据,实现了切换页面功能 上 ...

  4. 北京Uber优步司机奖励政策(3月19日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. 成都Uber优步司机奖励政策(3月27日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. Java:二进制(原码、反码、补码)与位运算

    一.二进制(原码.反码.补码) 二进制的最高位是符号位(“0”代表正数,“1”代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1.  原码:将一个整数转换成二进制表示 以 int ...

  7. 4、Java并发编程:synchronized

    Java并发编程:synchronized 虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就 ...

  8. Java 递归 反射 正则表达式

    一 递归 1. 就是函数自身调用自身 (就是在栈内存中不断的加载同一个函数) 2. 什么时候用递归呢? 当一个功能被重复使用 而每一次使用该功能时的参数不确定 都由上次的功能元素结果来确定 简单说: ...

  9. 【WXS数据类型】RegExp

    生成 regexp 对象需要使用 getRegExp函数,注意与JS的使用方法不同( new RegExp(pattern,modifiers);) 原型:getRegExp(pattern, mod ...

  10. 【转】cocos2d工具汇总

    位图字体工具Bitmap Font Tools BMFont (Windows)FonteditorGlyph DesignerHieroLabelAtlasCreator 粒子编辑工具Particl ...