C++Builder 程序员博客
20 May
小弟我在做一个程序,在查询完后,在dbgrid中游标移动到该条记录并使其改变颜色,但好像只能在OnDrawColumnCell中写,只是在form显示的时候颜色可以改变。在按钮中写语句通过了,可是颜色依然不改。
请指教一下,如何在按钮的事件中再去响应一个dbgrid的OnDrawColumnCell事件,给选中的记录改变颜色。
void __fastcall TDataMod::DBGDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumnEh *Column,
Gridseh::TGridDrawState State)
{
TDBGridEh* sgGrid = dynamic_cast <TDBGridEh*>(Sender);
if(State.Contains(Gridseh::gdSelected) )
{
sgGrid->Canvas->Brush->Color = TColor(RGB(49,106,197));
sgGrid->Canvas->Font->Color = TColor(RGB(255,255,255));
// sgGrid->Canvas->Font->Name = "宋体";
// sgGrid->Canvas->Font->Size = 14;
sgGrid->Canvas->FillRect(Rect);
}
else if ( Column->Field->DataSet->RecNo %2 == 0)
{
sgGrid->Canvas->Brush->Color = TColor(RGB(231,240,187));
sgGrid->Canvas->Font->Color = TColor(RGB(10,10,10));
//sgGrid->Canvas->Font->Name = "宋体";
// sgGrid->Canvas->Font->Size = 14;
sgGrid->Canvas->FillRect(Rect);
//sgGrid->Canvas->TextOutA()
}
else
{
sgGrid->Canvas->Brush->Color = TColor(RGB(247,255,214));
sgGrid->Canvas->Font->Color = TColor(RGB(10,10,10));
//sgGrid->Canvas->Font->Name = "宋体";
//sgGrid->Canvas->Font->Size = 14;
sgGrid->Canvas->FillRect(Rect);
}
String str;
if(Column->Field== NULL)
str="";
else
{
if(Column->DisplayFormat == "0.00")
str = FormatFloat("0.00", Column->Field->AsFloat);
else
str = Column->Field->AsString;
}
sgGrid->Canvas->Pen->Width = 1;
sgGrid->Canvas->Pen->Style = psSolid;
sgGrid->Canvas->Pen->Color = TColor(RGB(202, 218 ,119 ));
sgGrid->Canvas->MoveTo(Rect.Left,Rect.Bottom);
sgGrid->Canvas->LineTo(Rect.Right,Rect.Bottom) ;
sgGrid->Canvas->Pen->Color = TColor(RGB(202, 218 ,119 ));
sgGrid->Canvas->MoveTo(Rect.right,Rect.top);
sgGrid->Canvas->LineTo(Rect.Right,Rect.Bottom);
//sgGrid->Canvas->Rectangle(Rect);
DrawText(sgGrid->Canvas->Handle, str.c_str(),
-1, (RECT*)&Rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
}
只用
if(State.Contains(Gridseh::gdSelected) )
{
sgGrid->Canvas->Brush->Color = TColor(RGB(49,106,197));
sgGrid->Canvas->Font->Color = TColor(RGB(255,255,255));
sgGrid->DefaultDrawColumnCell(Rect,DataCol,Column,State);
}
大概这样是可以的,我最近刚弄过,绝对好用,不过记不太清楚了,如果不好用再联系。
干吗要画呢?本身就有属性的呀,设置dbRowSelect=true
行选择是dbgrid中本来就有的属性啊!
10 May
看了多位的介绍, 我按照以下做了,想变颜色,但就是变不了. 谢谢高手.
if(StoredProc4->RecNo%2==0 )
{
DBGrid1->Canvas->Brush->Color=clGrayText;
DBGrid1->Canvas->Font->Color=clBlue;
}
else
{
DBGrid1->Canvas->Brush->Color=clAppWorkSpace;
DBGrid1->Canvas->Font->Color=clRed;
}
DBGrid1->Canvas->Pen->Mode = pmMask;
DBGrid1->Canvas->FillRect(Rect);
DBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);
不是啊. 我想将表中的奇数行和偶数行设置成不同的颜色. 就是找不到切入点.
DBGrid 不随StoredProc4->RecNo%2==0 变化.
郁闷!
if(DBGrid1->DataSource->DataSet->Active==false) return;
if(DBGrid1->DataSource->DataSet->RecordCount <=0) return;
if (DBGrid1->DataSource->DataSet->RecNo % 2==1)
{
DBGrid1->Canvas->Font->Color=clBlack;
DBGrid1->Canvas->Brush->Color=clWindow;
}else{
DBGrid1->Canvas->Font->Color=clBlack;
DBGrid1->Canvas->Brush->Color=0×00D4D4D4; //clActiveBorder;
}
//================
if(State.Contains(gdSelected))
{
DBGrid1->Canvas->Font->Color = clWhite;
DBGrid1->Canvas->Brush->Color=clBlue;
}
DBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);
大哥, 我照你说的那样输入如下,可以运行,但颜色就是变不了. 整个报表都是第一个选项的结果. 说明程序起作用了,但偶数行没反映. 我的数据源是TStoredProc. 再帮一下. 谢谢!
if (DBGrid1->DataSource->DataSet->RecNo % 2==1)
{
DBGrid1->Canvas->Font->Color=clBlack;
DBGrid1->Canvas->Brush->Color=clWindow;
}
else
{
DBGrid1->Canvas->Font->Color=clBlack;
DBGrid1->Canvas->Brush->Color=0×00D4D4D4;
}
DBGrid1->Canvas->Pen->Mode = pmMask;
DBGrid1->Canvas->FillRect(Rect);
DBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);
发现问题了. TADOStoredProc就可以, 用TStoredProc就不行. 娘西匹!
问题解决了
恭喜你啊
来学习的!
24 Mar
DBGrid里要是显示大于0×7FFFFFFF的数,就会出现负值,原因是它只接受有符号的整数,
那请问下大于0×7FFFFFFF而小于0xFFFFFFFF 的数应该怎么样现在呢,我不想出现负值。
就是怎么样让它显示全部的不符号整数。
dataset里面的field的类型不对,找找有没有无符号数。如果是查询语句,可以在查询时转成字符串
把数据库字段改一下,改成DECIMAL比较好
感谢两位的关注,我把数据库字段改成largeint,还是不行,关键是在grid里写入值的时候,它是用AsInteger来接收的,而AsInteger确接受的是有符号的数.哎,难道真不能写入无符号的数.
首先感谢你对我的支持,我不知道你用什么数据库控件,我用的是clientdataset,它的field类型并没有BIGINT,只用
ftLargeint,我试了下用它自己控件添加一条超过0×8FFFFFFF值的记录是可以显示正数的,但是当我给数据库添加新记录
时用AsInteger就只能得到负数.
换成VALUE试下
我觉得应该是数据源的问题,你转成字符串型后存入数据库中,DBGRID显示字符串应该可以吧
调用DBGRID的自绘事件,自己把数字填进去。。。
感谢各位,只是字符串不能象数字那样很好的排序,VALUE值也不能显示成正数,我现在用64位写进去正数,但是
clientdataset的index排序的方法就不起作用,换成整型即使是负数显示都能进行排序,DBGRID的自绘事件的自绘事情太
烦琐了,因为数据太多,着个难道真是一个不能实现的功能?还得请高人指点.
谁有好的方法,给个建议撒!大家帮忙顶一下!
固定字符串长度可以实现以上功能,感谢大家的参与.
14 Mar
小虾问大虾,触发dbgrid的什么事件来把dbgrid中显示的数据导入word.在论坛中找了不少范例都一样,我点击了dbgrid的所有事件也没有找到与例子中类似的事件void __fastcall DBGrid2Word(TDBGrid *dbg, String strDocFile)…….?请教各位。
没用过DBGrid,可以获得DBgrid里的数据,再用ole写到word里把
用ole导出数据
老妖代码中的void __fastcall DBGrid2Word(TDBGrid *dbg, String strDocFile)事件是自定义事件。
不是DBGrid控件的系统中事件,所以你是找不到了。
定义方法,在头文件中public部分加入以下声明:
void __fastcall DBGrid2Word(TDBGrid *dbg, String strDocFile);
自定义函数
2 Jan
隔行显示不同色
void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
TGridDrawState State)
{
if (State.Contains(gdSelected))
return;
if (DBGrid1-> DataSource-> DataSet-> RecNo % 2 ==0)
DBGrid1-> Canvas-> Brush-> Color = clRed; //定义背景颜色
else
DBGrid1-> Canvas-> Brush-> Color = clBlue; //定义背景颜色
DBGrid1-> DefaultDrawColumnCell(Rect,DataCol,Column,State);
}
为什么DBGrid1-> DataSource-> DataSet-> RecNo 的值总是等于-1?
另外DBGrid能不能设置在编辑时不自动保存,而是在我按一个保存的按钮后再保存?因为DBGrid上有些字段是隐藏的,在保存前需要先赋值,而在编辑时,先用Query1-> Edit(),在保存按钮下的代码中用了Query1-> Post()也不保存修改或添加的记录,请问这样做对应的Query与DataSource控件的属性如何设置,那个保存按钮的代码如何写呢?
第二个问题
DBGrid1-> DataSource-> DataSet-> LockType=ltBaltchOptimistisc
保存时调用query的updatebatch()函数
RecNo 对于 paradox 和dbf 才是有意义的,他的说明写了。
DBGrid1-> DataSource-> DataSet-> LockType=ltBaltchOptimistisc
程序编译时这里都会出错啊,DataSet没有LockType属性
在程序中我把Query1-> CachedUpdates=true;Query1-> RequestLive=true;在修改时调用了Query1-> Edit()方法,修改过程同时还有添加了新记录,保存时调用了Query1-> Post()方法,但什么也保存不了啊。有什么方法可以保存呢?
Query1-> CachedUpdates=true这样的话你试试Query1-> ApplyUpdates();
另外 对于BDE控件,RecNo 的值总是等于-1。
该回复于2008-07-10 02:44:24被版主删除
该回复于2008-07-10 02:56:32被版主删除
学习,强烈需要
RT,在线等高手解决问题,希望贴出完整代码,本人是新手,分数不是问题,感谢!
将其字段的checkbox设为true就会有checkbox 了
Ehlib是第三方控件,不过做数据库编程来说已经替代默认BCB自带的DBGrid什么的控件了,属于增强版.老妖网站上有
不要第3方控件应该怎么实现呢
up
实现不了…不是吧
void __fastcall TForm1::OnDrawColumnCell1(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { int Select_Check[2]={DFCS_BUTTONCHECK,DFCS_BUTTONCHECK |DFCS_CHECKED} ; if (Column->Field->DataType== ftBoolean ) { TRect RecTemp; RecTemp.left = Rect.Left; RecTemp.right = Rect.Right; RecTemp.top = Rect.Top; RecTemp.bottom = Rect.Bottom; DBGrid1->Canvas->FillRect(Rect); DrawFrameControl(DBGrid1->Canvas->Handle,&RecTemp,DFC_BUTTON, Select_Check[Column->Field->AsBoolean?1:0]); } } //————————————————————————— void __fastcall TForm1::CellClick(TColumn *Column) { if (!Column->Field->DataSet->Eof) { if (Column->Field->DataType == ftBoolean ) { SaveBoolean(); } } } //————————————————————————— void __fastcall TForm1::KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if ((Key ==VK_DOWN) && (ADOQuery1->RecNo==ADOQuery1->RecordCount)) Key=NULL; if ((Key==VK_SPACE)&& (DBGrid1->SelectedField->DataType==ftBoolean)) { SaveBoolean(); } } //————————————————————————— void __fastcall TfrmGatByRec::SaveBoolean()//这段出错,不知道格式怎么写 { DBGrid1->SelectedField->DataSet->Edit(); DBGrid1->SelectedField->AsBoolean=!DBGrid1->SelectedField->AsBoolean; DBGrid1->SelectedField->DataSet->Post(); }
幫我看下上面代碼是實現什么功能,注釋那是出錯了,謝謝
沒人幫忙?????????
16 Dec
因为数据库中有一个文本型的Field,
我要判断这个Field的值是否符合要求,
没法用SQL语句来选择,
而且数据量不是很多,
所以想用代码一条一条地判断,
符合的就在DBGrid中显示。
不知有什么办法可以实现?
怎么会没法用SQL语句判断呢?
void __fastcall TForm1::ADOQuery1FilterRecord(TDataSet *DataSet, bool &Accept) { //这里写上你过滤的代码,比如你可以在那个‘text’类型字段中搜索某个你认为的关键的东东 搜索到了就让 Accept= true; Accept = IsIWant(….) ;// 。。 } //—————————————————————————
谢谢jxw1987628,问题解决了。
另外,
hnzlk:
我的数据库有一个Field,
用来保存温度的,
而如果温度传感器不接或短路时,
这个Field里的值不是一个数值,
而是“断线”或“短路”这样的文本,
所以我只能把这个Field定义为文本型。
这样的话怎么用SQL去筛选温度值大于30度而小于50度的记录呢?
可另开帖给分。
顶小漫
ADOQuery1->Filtered=true;
怎么用SQL去筛选温度值大于30度而小于50度的记录呢
select * from 表
where case when isnumeric(温度)=1 then cast(温度 as float) else 0 end between 30 and 50
12 Dec
还没弄明白DBGrid是怎么绑定数据显示出来呢,
拖DBGrid,TADOQuery,DataSource到界面中,
//DBGrid数据查询
AnsiString strdataBind;
qryDataBind->Close();
qryDataBind->SQL->Clear();
strdataBind="select * from 化验数据";
qryDataBind->SQL->Add(strdataBind);
qryDataBind->Open();
DBGrid中的FileName没有数据,点击了提示TADOQuery,Missing SQL property
没有找到少设置什么了,给提示下
没有ADOCONNECTION吧,你数据源可能都没有设置
ADOConnection1,DBGrid,ADOQuery,DataSource 设置ADOQuery的SQL语句以及connection,并设置DataSource的dataset,并设置DBGrid的datasource,当然前提要让 ADOConnection1连上数据库,把ADOQuery的active设为true就能看到数据了。
DataSource->DataSet设为ADOQuery
DBGrid->DataSource设为DataSource
这样当ADOQuery里有数据里,DBGrid就会显示了。
4 Dec
在DBGrid显示数据的同时,还有一个线程在源源不断的对数据库写记录。
一般情况下,DBGrid是能静态显示数据库数据的。但是由于数据源不断更新,请问怎么解决这样的冲突?
现在的问题是,在有新数据进入数据表之后,DBGrid刷新成空表格。
// 你是在其他工作线程里面刷新DBGrid ? // 还是在主线程里面刷新DBGrid ?
// 保持静态的,那你干脆就不要用DBGrid了 // 以为DBgrid这种需要和数据集(Query等) 数据源控件(Datasource等)实时挂接 // 你换成其他的表格控件如StringGrid,这种数据就是静态的,你读取了多少,往里面 // 添加就ok了,
记录 DataSet 的 RecNo,刷新,或者是关闭表,再重新开启表,再恢复 DataSet RecNo
但如果你是用 DataSet 的方法直接插入数据,那么和该 DataSet 控件绑定的 DBGrid 会自动刷新,但如果是 SQL 命令插入的数据,你就只能使用记录 RecNo 的方法来保持原来的游标,或者刷新后直接将游标移动到最有一个记录 DataSet 的 Last() 方法
不要用DBGrid,直接用StringGrid,其他线程插入一条就显示一条。
有什么办法可以在载入过一次之后关掉DBGRID或者DATASOURCE?
想要再次载入的时候再打开?
请大虾帮帮忙
谁帮忙解决下哈,分不够可以额外加
不知道你的数据载入是如何做的。如果本身DBGRID的Dataset没有改变,其控件是无法得知数据源的数据是否有变更的,前面已经说过用轮询的办法。
数据载入就是自动的载入的,链接上DATASOURCE就可以了,没有额外的操作。
轮询是指用一个计时器定时刷新吧?
那到了时间后,怎么让他重新载入一次数据呢?
ado_Query->SQL->Add("select *from TAB");这样来加数据到DBGRID里去的
“还有一个线程在源源不断的对数据库写记录”是怎么实现的?
动态的加载数据,控件使用静态的。
能否用一个临时表中转.
当有新数据时对临时表操作.
怎么判断DBGRID已经载入了数据,我把ACITIVE关了呢?
可以看临时表是否有数据就知道 DBGRID是否已经载入了数据
这个问题还是没有搞定。
请大虾们帮忙。
我把问题再阐述一遍:DBGrid显示SQL里的数据,但是由于SQL里的数据是在即时更新的,这样怎么让DBGrid也在即时变化?
请大虾们指教。可能的话,希望说的越详细越好。
28 Nov
//删除多选的记录
void __fastcall TForm1::N1Click(TObject *Sender)
{
for(int i=0;i <(DBGrid1->SelectedRows->Count);i++)
{
DBGrid1->DataSource->DataSet->Bookmark=DBGrid1->SelectedRows->Items[i];
DBGrid1->DataSource->DataSet->Delete();
}
}
但是记录已经删除了DBGrid1->SelectedRows->Count还是不变,除非重新选择记录.这样很容易出错.
高人指点一下.
不行,还是没有更新DBGrid1->SelectedRows->Count的值.
把这个DBGrid的DataSource的Enabled设置成false,再恢复为true试试
要将MultiSelect 设为True
以上都不行,是不是BUG啊
删除数据后
执行 selcet * from….
搜索出数据,显示就不会错了
删完了,刷新一下数据集
你的Bookmark用来干啥的? 代码不怎么完整!
for(int i=0;i <DBGrid1->SelectedRows->Count;i++)
{
DBGrid1->DataSource->DataSet->GotoBookmark((void *)fm_ch_prod->DBGrid1->SelectedRows->Items[i].c_str()); //定位 如果有的话
DBGrid1->DataSource->DataSet->Delete();
}
汗…….改的不对…..
修改版
for(int i=0;i <DBGrid1->SelectedRows->Count;i++)
{
DBGrid1->DataSource->DataSet->GotoBookmark((void *)DBGrid1->SelectedRows->Items[i].c_str()); //定位 如果有的话
DBGrid1->DataSource->DataSet->Delete();
}