以下是我从网上看见的实现代码:
在设计过程中,有时候数据较大量,field 较多的时候,只是点击单元格可能会对某个field的数据误操作(如数据错行),为此才会想到这个问题,解决办法如下:
    点击单元格就改当前行颜色。这个办法也算是没办法的办法吧!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:=$84;
   end
   else
   begin
     Canvas.Brush.Color:=Color;
     Canvas.Font.Color:=Font.Color;
   end;
   DefaultDrawColumnCell(Rect,DataCol,Column,State);
 end;
end; 测试通过(d7)! 但D7通过了却在kylix不通过
请问原因是.....?

解决方案 »

  1.   

    将DBGrid的options的dgAlwaysShowSelection属性设为true,可以实现点击单元格选中一整行。
    把dgEditing属性设为true,可以实现对单元格进行编辑
      

  2.   

    unit uDBGrid;interfaceuses Windows, DBGrids, Classes, Messages, Types, Grids, Graphics, Forms
      , DB, SysUtils, Controls;type
      TDBGrid = class(DBGrids.TDBGrid)       
      private
        FVertScrollBar: Boolean;
        FOldGridWnd: TWndMethod;
        FOddRowColor: TColor;
        FEvenRowColor: TColor;
        FActiveRowColor: TColor;
        FOriginalOptions: TDBGridOptions;
        FAllowAppend: Boolean;
        procedure NewGridWnd(var aMessage: TMessage);
      protected
        procedure ColEnter; override;
        procedure ColExit; override;
        procedure KeyDown(var Key: Word; Shift: TShiftState); override;
        procedure DrawCell(aCol, aRow: Longint; aRect: TRect;
          aState: TGridDrawState); override;
        procedure Scroll(Distance: Integer); override;
        procedure Paint; override;
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        property AllowAppend: Boolean read FAllowAppend write FAllowAppend default True;
        property InplaceEditor;
        property OddRowColor: TColor read FOddRowColor write FOddRowColor default clCream;
        property EvenRowColor: TColor read FEvenRowColor write FEvenRowColor default clMoneyGreen;
        property ActiveRowColor: TColor read FActiveRowColor write FActiveRowColor default $00E7CFFF;
        property VertScrollBar: Boolean read FVertScrollBar write FVertScrollBar default True;
      end;implementation{ TDBGrid }constructor TDBGrid.Create(AOwner: TComponent);
    begin
      inherited;
      FOldGridWnd := WindowProc;
      WindowProc := NewGridWnd;
      FOddRowColor := clCream;
      FEvenRowColor := $00FFF2E8;
      FActiveRowColor := $00F2E8FF;
      FVertScrollBar := True;
      AllowAppend := False;
    end;destructor TDBGrid.Destroy;
    begin
      WindowProc := FOldGridWnd;
      inherited Destroy;
    end;procedure TDBGrid.DrawCell(aCol, aRow: Integer; aRect: TRect;
      aState: TGridDrawState);
      function RowIsMultiSelected: Boolean;
      var
        Index: Integer;
      begin
        Result := (dgMultiSelect in Options) and Datalink.Active and
          SelectedRows.Find(Datalink.Datasource.Dataset.Book, Index);
      end;
    var
      lOldActiveRecord: Integer;
      lDrawColumn: TColumn;
    begin
      if not Assigned(DataSource) then exit;
      if not Assigned(DataSource.DataSet) then exit;
      if not DataSource.DataSet.Active then exit;  if (dgTitles in Options) and (ARow = 0)
        or (gdFixed in AState) and (ACol - IndicatorOffset < 0) then
      begin
        inherited DrawCell(ACol, ARow, ARect, AState);
        Exit;
      end;
      if (dgTitles in Options) then Dec(ARow);
      Dec(ACol, IndicatorOffset);
      if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options =
        [dgRowLines, dgColLines]) then
        InflateRect(ARect, -1, -1)
      else
        with Canvas do
        begin
          lDrawColumn := Columns[ACol];
          if not lDrawColumn.Showing then Exit;
          Font := lDrawColumn.Font;
          Brush.Color := lDrawColumn.Color;
          Font.Color := lDrawColumn.Font.Color;
          if Odd(ARow) then Brush.Color := FEvenRowColor
          else Brush.Color := FOddRowColor;
          if (aCol = 0)
            and (lDrawColumn.Field.FieldKind = fkCalculated) then
            Brush.Color := clBtnFace;      if not Assigned(DataLink) or not DataLink.Active then
            FillRect(ARect)
          else
          begin
            if ARow >= 0 then
            begin
              lOldActiveRecord := DataLink.ActiveRecord;
              try
                DataLink.ActiveRecord := ARow;
                if (DataLink.ActiveRecord = Row - 1) or RowIsMultiSelected then
                begin
                  Font.Color := clBlack;
                  Brush.Color := FActiveRowColor;
                end;
                if DefaultDrawing then
                  DefaultDrawColumnCell(ARect, ACol, LDrawColumn, AState);
                if Columns.State = csDefault then
                  DrawDataCell(ARect, lDrawColumn.Field, AState);
                DrawColumnCell(ARect, ACol, lDrawColumn, AState);
              finally
                DataLink.Activerecord := lOldActiveRecord;
              end; // end try
            end; // end if aRow > 0        if DefaultDrawing and (gdSelected in AState) and
              ((dgAlwaysShowSelection in Options) or Focused)
              and not (csDesigning in Componentstate)
              and not (dgRowSelect in Options)
              and (ValidParentForm(self).ActiveControl = self) then
            begin
              Windows.DrawFocusRect(Handle, ARect);
              Canvas.Brush.COlor := clNavy;
              Canvas.FillRect(ARect);
              Canvas.Font.Color := clWhite;
              Canvas.Font.Style := [fsBold];
              DefaultDrawColumnCell(ARect, ACol, lDrawColumn, AState);
            end;
          end;
        end;  if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options =
        [dgRowLines, dgColLines]) then
      begin
        InflateRect(ARect, -2, -2);
        DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
        DrawEdge(Canvas.Handle, ARect, BDR_SUNKENINNER, BF_TOPLEFT);
      end;
    end;procedure TDBGrid.NewGridWnd(var aMessage: TMessage);
    var
      IsNeg: Boolean;
    begin
      if (aMessage.Msg = WM_MOUSEWHEEL)
        and DataSource.DataSet.Active then
      begin
        IsNeg := short(aMessage.WParamHi) < 0;
        if IsNeg then
          DataSource.DataSet.MoveBy(1)
        else
          DataSource.DataSet.MoveBy(-1)
      end
      else
        FOldGridWnd(aMessage);
    end;procedure TDBGrid.Paint;
    begin
      if not FVertScrollBar then
        SetScrollRange(Self.Handle, SB_VERT, 0, 0, False);
      inherited Paint;
    end;procedure TDBGrid.Scroll(Distance: Integer);
    begin
      inherited Scroll(Distance);
      Refresh;
    end;procedure TDBGrid.KeyDown(var Key: Word; Shift: TShiftState);
    var
      lStateChange: TNotifyEvent;
    begin
      inherited;
      if (Key = VK_Space)
        and not SelectedField.ReadOnly
        and (SelectedField is TBooleanField) then
      begin
        lStateChange := DataSource.OnStateChange;
        DataSource.OnStateChange := nil;
        try
          DataLink.DataSet.Edit;
          SelectedField.AsBoolean := not SelectedField.AsBoolean;
          DataLink.DataSet.Post;
        finally
          DataSource.OnStateChange := lStateChange;
        end;
      end;  if (not FAllowAppend) and (DataLink.DataSet.Eof) and (Key = VK_DOWN) then
      begin
        Key := 0;
        DataLink.DataSet.Cancel;
      end;
    end;procedure TDBGrid.ColEnter;
    begin
      inherited;
      if SelectedField is TBooleanField then
      begin
        FOriginalOptions := Options;
        Options := Options - [dgEditing];
      end;
    end;procedure TDBGrid.ColExit;
    begin
      inherited;
      if SelectedField is TBooleanField then
        Options := FOriginalOptions
    end;end.
      

  3.   

    上面是我写的一个DBGrid, 重写了DrawCell方法
    你只要在你的单元里加入
    Type
      TDBGrid = uDBGrid.TDBGrid;就可以看到效果啦.
      

  4.   

    要编辑的话先打开再EDIT就可以了阿。你单击到某一个上的时候就是选中了那一行阿。
    如果要把一行都有选中的郊果的话好像有属性可以设的