高分求解StringGrid显示房态问题。分不够可以再加 (100分)

  • 主题发起人 主题发起人 LanderLiu
  • 开始时间 开始时间
L

LanderLiu

Unregistered / Unconfirmed
GUEST, unregistred user!
题是这样的,STRG_TableState是一个显示房态的StringGrid:
1:调用如下:
procedure TF_CashMain.STRG_TableStateDrawCell(Sender: TObject;
ACol,
ARow: Integer;
Rect: TRect;
State: TGridDrawState);
begin
RefreshStringGrid(arow,acol,Rect);
end;
2:实调用的函数RefreshStringGrid如下:其中P_OpenADOQueryWithC2为一函数根据传入的ADOQuery,表名,条件字段名1,条件字段值1,条件字段名2,条件字段值2,两个条件打开一个表.
procedure RefreshStringGrid(row,col:integer;Rect: TRect);
//根据传入的参数确定StringGrid显示内容
begin
P_OpenADOQueryWithC2(DM_1.ADOQ_RoomState,'RoomState','F_RS_DeptCode',inttostrM_DeptID),'F_RS_Code',RightStr('000'+inttostr(row*8+col+1),3));
if DM_1.ADOQ_RoomState.RecordCount = 0 then
exit;
with DM_1.ADOQ_RoomStatedo
begin
case strtoint(FieldByName('F_RS_StateCode').AsString) of
1: begin
STRG_TableState.Canvas.Brush.color:=clred;
end;
2: begin
STRG_TableState.Canvas.Brush.color:=clwhite;
end;
3: begin
STRG_TableState.Canvas.Brush.color:=clSilver;
end;
4: begin
STRG_TableState.Canvas.Brush.color:=clGradientActiveCaption;
end;
end;
//case
STRG_TableState.Canvas.FillRect(rect);
STRG_TableState.Canvas.Brush.Style:=bssolid;
STRG_TableState.Canvas.textOut(col*65+5,row*42,fieldbyname('F_RS_Code').asstring);
STRG_TableState.Canvas.textOut(col*65+5,row*42+15,fieldbyname('F_RS_Name').asstring);
end;
//with
end;
3:现在的问题是如果表中的数据即房间多的时候刷新会变得很慢,而且如果这个StringGrid要滚动的话下面的就不会显示文字而且点上面的文字时文字也会不见,我试验的数据刚100个已经刷新很慢了,如果再多了有了滚动就糟了.我查了一些书但关于这方面的介绍了了无几, 我也找不出一个好的解决方法和思路,现高分向各位FW求救,如果方便请贴出来,也可以发到我的邮箱 liuyongsheng2003@hotmail.com ,如果能帮我解决我可以再送200分.
 
自已,等待救命。
 
分不够可以加请DFW们帮帮。
 
你做酒店管理软件???
用StringGrid做房态不好!最好换一种办法~!或者用别的组件!
不然你会死的很惨~!^_^!
 
我做过酒店,餐饮软件,StringGrid不止速度问题,还刷新时的闪烁问题,最后我用动态生成SpeedButton,现在使用很正常,就是有点烦
 

DrawCell里不要连数据库
要提前把相关的数据取出
 
to yue_shan:
有没有一个思路给我说说?^-^
to hfghfghfg,
你的方法我试试。
 
hfghfghfg的方法是正解。stringgrid一定比speedbutton性能好,只要你控制得好。就速度和闪烁问题上看,SpeedButton也并不比StringGrid优越到哪去。
你可以将房态变成一个内存对象。你要知道,DrawCell事件并不是数据变了才触发(反而房态变了不一定触发),而是如果窗口被别的画面盖住了然后又露出来了才会触发。如果内存对象中的内容变了,你还有机会主动触发这个事件。
 
to barton
有收获。
 
hfghfghfg的方法是正解。stringgrid的DrawCell事件中不能写数据的查询。LanderLiu看你的代码好像是每个cell都有一个sql查询。能不能整个stringgrid的内容用一个sql查询。然后根据这个结果来绘制stringgrid。这个方法不慢。我写过的mis系统中上万条数据,也不感觉慢。
 
Lfish的说法非常好。如果你对面向对象的方法不太熟,也可以用一个持久的Dataset来保存房态。DrawCell方法刚好让你来弥补StringGrid没有数据感知的缺憾。
 
多谢各位,我在FormShow的时候取出房态,在DrawCell的时候绘制房态,现在速度方面已经可以接受了,但我出此贴时的第二个问题解决不了,就是如果绘到StringGrid的不可见部分,也就是滚动出去的部分就显示不正常了,没有了文字。不知在哪个事件中再增加代码。请各位FW多多指教。
 
To:LanderLiu
我遇到你你差不多的问题,只不过我是显示文字,用的是Drawtext()函数。
也是你说的第三中情况!据说,StringGrid控件解决不了!我已经准备换控件了!
不过,我最希望用Delphi本身的控件,如果你这能解决,太好了!
支持楼主!!!!如能解决我也给100分!
 
to hfghfghfg,
我在FormShow时取出数据,在DrawCell里绘图,速度方面快了很多,如果我执行一个改某个单元格状态的动作,应该这个单元会重绘,改变顔色才对但现在他没反应,如果关了主窗口再打开他就会有变化,我分析应该是在改变状态后StringGrid应该重绘,但不知道是哪里的问题他没有自动执行这个动作。我试了StringGrid.Refresh和StringGrid.Repaint这两个命令,没反应,是不是用错了?
各位DFW有没有能帮我解决一的?
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
ColorBox1: TColorBox;
procedure StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
procedure ColorBox1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var
str: string;
TextRect: TRect;
begin
//
with TstringGrid(Sender)do
begin
if gdFixed in State then
begin
Canvas.Brush.Color := $00E1E1E1;
Canvas.Font.Color := clblack;
end
else
if gdSelected in State then
begin
Canvas.Brush.Color := $00F9C89A;
Canvas.Font.Color := clWhite;
end
else
begin
Canvas.Brush.Color := $00F8F4F0;
Canvas.Font.Color := clblack;
end;

Canvas.FillRect(rect);
str := cells[ACol, ARow];
if str <> '' then
Canvas.Font.Color := StringToColor(str);
TextRect := Rect;
inc(Rect.Top, 3);
inc(Rect.Left, 3);
if ARow = 0 then
drawTEXT(Canvas.Handle, pchar(str), length(str), rect, DT_CENTER)
else
drawTEXT(Canvas.Handle, pchar(str), length(str), rect, DT_LEFT)
end;

end;

procedure TForm1.ColorBox1Change(Sender: TObject);
begin
with StringGrid1do
begin

cells[col, row] := ColorBox1.ColorNames[ColorBox1.ItemIndex];
end;
end;

end.



object Form1: TForm1
Left = 192
Top = 103
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object StringGrid1: TStringGrid
Left = 48
Top = 16
Width = 329
Height = 330
DefaultRowHeight = 64
DefaultDrawing = False
FixedCols = 0
FixedRows = 0
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine]
TabOrder = 0
OnDrawCell = StringGrid1DrawCell
end
object ColorBox1: TColorBox
Left = 464
Top = 48
Width = 145
Height = 22
ItemHeight = 16
TabOrder = 1
OnChange = ColorBox1Change
end
end
 
to hfghfghfg,
你的方法我试过了,很不错,不过可能用不到我做的东东上,我要求是根据已有的数据判定画布显示的显示方式(顔色、文字),我前面的方法其实差不多了,只是在不可见部分滚动出来以后就显示不了了,我想应该有一个事件在StringGrid滚动时触发并重绘画布,但不知道这段代码怎么写。
大家有没有好的方法,请不悯赐教。
 
找找关于截获滚动的消息看看,然后给grid发一个重画的消息。
具体我就不会做了。
 
建议
STRG_TableState.Canvas.textOut(col*65+5,row*42,fieldbyname('F_RS_Code').asstring);
改为:
STRG_TableState.Canvas.TextRect(Rect,Rect.left+2,Rect.top+2,STRG_TableState.Cells[ACol,ARow]);
就在事件里写 STRG_TableStateDrawCell(Sender: TObject;
ACol,
ARow: Integer;
Rect: TRect;
State: TGridDrawState);
 
我的程序两万条记录都不慢嘛,呵呵,不是每个格都显示不同颜色,是每条记录
试试看吧
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
636
import
I
I
回复
0
查看
571
import
I
S
回复
0
查看
951
SUNSTONE的Delphi笔记
S
后退
顶部