在DBGrid中,怎样才能让我能点击一个单元格选择整行,又可以编辑单元格的内容呢

aivinok 2005-08-22 05:39:19
以下是我从网上看见的实现代码:
在设计过程中,有时候数据较大量,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不通过
请问原因是.....?
...全文
206 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
loon1981 2005-08-22
  • 打赏
  • 举报
回复
要编辑的话先打开再EDIT就可以了阿。

你单击到某一个上的时候就是选中了那一行阿。
如果要把一行都有选中的郊果的话好像有属性可以设的
konhon 2005-08-22
  • 打赏
  • 举报
回复
上面是我写的一个DBGrid, 重写了DrawCell方法
你只要在你的单元里加入
Type
TDBGrid = uDBGrid.TDBGrid;

就可以看到效果啦.
konhon 2005-08-22
  • 打赏
  • 举报
回复
unit uDBGrid;

interface

uses 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.Bookmark, 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.
cxtx 2005-08-22
  • 打赏
  • 举报
回复
将DBGrid的options的dgAlwaysShowSelection属性设为true,可以实现点击单元格选中一整行。
把dgEditing属性设为true,可以实现对单元格进行编辑
hqhhh 2005-08-22
  • 打赏
  • 举报
回复
kylix没用过!收藏!

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧