DBGrid怎样实现自适应列宽,找过一些代码,可是都不如意
解决方案 »
- http://delphi.ktop.com.tw/ 这个台湾网站永久关闭了吗?有没有知情的朋友进来说说?
- 写程序时的自动提示是怎么个思路啊
- delphi控件edit透明?
- 怎么声明type library里的method
- CORBA 开发的朋友请留下QQ或MSN,有问题请教,Gatekeeper 问题发了N多贴也未搞定。
- DELPHI里如何设置一个文件夹属性为隐藏呢?在线等待
- 卖!!!!!
- 怎样调用系统默认的邮件收发工具?
- 100分调查各位朋友用什么软件制作setup安装文件?
- 怎样将DELPHI的编辑器全屏?
- 请教各位高手,如何将记录号加到dbgrid 中?
- 如何设计stringgrid控件
//让好几个Show和OnResize事件“定位”到这个
{
int I;
TComponent *Temp;
for(I=ComponentCount-1;I>=0;I--)
{
Temp=Components[I];
if(dynamic_cast<TDBGrid *>(Temp)!=NULL)
{
TDBGrid* dgrid=(TDBGrid *)(Temp);
TADOQuery *dset=(TADOQuery *)dgrid->DataSource->DataSet;
int count,fontSize,k;
count=dgrid->Columns->Count;
fontSize=dgrid->Font->Size;
k=count;
while(k-->0)
dset->Fields->Fields[k]->DisplayWidth=(dgrid->ClientWidth)/(count+1)/fontSize;
//因为取整的缘故,让 “列”数多1个
}
}
}
这句话是什么意思?
我的意思是:DBGrid的某一列的宽度随着它内容长度的增减而相应增减
假设这个列目前最长的内容是5个汉字时,那么就让它有5个汉字那么宽
提示:Access violation at address 00401D74 in module 'Project1.exe'
也没有用BDE数据集合连dbgrid.要完全用我的代码,适当得改改
我有这样几个疑问,探讨一下:
int I;
TComponent *Temp;
for(I=ComponentCount-1;I>=0;I--)
{
Temp=Components[I];
这段代码是遍历Form上的所有控件的吧,我发现它把所有的控件都遍历了一遍。能不能筛选只遍历DBGrid?
还有,dbgrid事先要连接好数据,是必须要在设计期连接还是也可以在这段代码执行之前用代码连接?
strSql="select * from MouldInfoH";
frmDm->qryDbgm->Close();
frmDm->qryDbgm->SQL->Clear();
frmDm->qryDbgm->SQL->Add(strSql);
frmDm->qryDbgm->Open();
//DBGrid自适应列宽
TADOQuery *dset=(TADOQuery *)dbgMouldH->DataSource->DataSet;
int count,fontSize,k;
count=dbgMouldH->Columns->Count;
fontSize=dbgMouldH->Font->Size;
k=count;
while(k-->0)
dset->Fields->Fields[k]->DisplayWidth=(dbgMouldH->ClientWidth)/(count+1)/fontSize;
1 遍历:只有这办法遍历所有TDBGrid,是得针对TComponent判别。
2 关于连接:是事先连好。
3 效果:我从新看了,还得
OnResize事件“定位”到这个事件上
如果这个“定位”你不熟:
代码复制一份进入窗得OnResize事件
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ADOTable1->Open();
int count,fontSize,k;
count=DBGrid1->Columns->Count;
fontSize=DBGrid1->Font->Size;
k=count;
while(k-->0)
DBGrid1->DataSource->DataSet->Fields->Fields[k]->DisplayWidth=
(DBGrid1->ClientWidth)/(count+1)/fontSize;
}
//---------------------------------------------------------------------------
干脆不遍历了,专门重新写代码给你
__published: // IDE-managed Components
TADOConnection *ADOConnection1;
TADOTable *ADOTable1;
TDataSource *DataSource1;
TDBGrid *DBGrid1;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);这下一点没问题,刚实验
#pragma hdrstop#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
int mWth = 0; for (int c = 0;c < DBGrid1->Columns->Count;c ++)
{
ADOTable1->First();
while(!ADOTable1->Eof)
{
switch(DBGrid1->Columns->Items[c]->Index)
{
case 0:
if (mWth <= AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsString).Length() * 6)
mWth = AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsString).Length() * 6;
DBGrid1->Columns->Items[DBGrid1->Columns->Items[c]->Index]->Width = mWth;
break;
case 1:
if (mWth <= AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsInteger).Length() * 6)
mWth = AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsInteger).Length() * 6;
DBGrid1->Columns->Items[DBGrid1->Columns->Items[c]->Index]->Width = mWth;
break;
case 2:
if (mWth <= AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsFloat).Length() * 6)
mWth = AnsiString(DBGrid1->Fields[DBGrid1->Columns->Items[c]->Index]->AsFloat).Length() * 6;
DBGrid1->Columns->Items[DBGrid1->Columns->Items[c]->Index]->Width = mWth;
break;
}
ADOTable1->Next();
}
}
}
//---------------------------------------------------------------------------
而这时Form的ReSize事件并没有发生
如果是这种情况,我觉得你的这段代码肯定就不适应了
最小化最大化切换一下看效果
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select * from MouldInfoH");
ADOQuery1->Open();
TADOQuery *dset=(TADOQuery *)DBGrid1->DataSource->DataSet;
int count,fontSize,k;
count=DBGrid1->Columns->Count;
fontSize=DBGrid1->Font->Size;
k=count;
while(k-->0)
dset->Fields->Fields[k]->DisplayWidth=(DBGrid1->ClientWidth)/(count+1)/fontSize;
}
//---------------------------------------------------------------------------
应该没问题吧
{
dset->Fields->Fields[k]->DisplayWidth=(DBGrid1->ClientWidth)/(count+1)/fontSize;
ShowMessage(dset->Fields->Fields[k]->DisplayWidth);
}
每次ShowMessage都是1
{
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select * from myTable");
ADOQuery1->Open();
TADOQuery *dset=(TADOQuery *)DBGrid1->DataSource->DataSet;
int count,fontSize,k;
count=DBGrid1->Columns->Count;
fontSize=DBGrid1->Font->Size;
k=count;
while(k-->0)
dset->Fields->Fields[k]->DisplayWidth=
(DBGrid1->ClientWidth)/(count+1)/fontSize;
}
好着,
你将窗题大小改改,再按button可看出效果
TADOQuery *dset=(TADOQuery *)DBGrid1->DataSource->DataSet;
加括号
TADOQuery *dset=(TADOQuery *)(DBGrid1->DataSource->DataSet);
看看
除了这个,没有别的办法了么?
var
jsq,maxWidth:integer;
begin
DBGridName.DataSource.Dataset.DisableControls;
for jsq:=0 to DBGridName.Columns.Count-1 do
begin
DBGridName.DataSource.Dataset.First;
maxWidth:=DBGridName.Canvas.TextWidth(trim(DBGridName.Columns[jsq].Title.Caption));
while not DBGridName.DataSource.Dataset.Eof do
begin
if maxWidth<DBGridName.Canvas.TextWidth(trim(DBGridName.DataSource.Dataset.fieldbyname(DBGridName.Columns[jsq].FieldName).AsString)) then
maxWidth:=DBGridName.Canvas.TextWidth(trim(DBGridName.DataSource.Dataset.fieldbyname(DBGridName.Columns[jsq].FieldName).AsString))
else
DBGridName.DataSource.Dataset.Next;
end;
DBGridName.Columns[jsq].Width:=maxWidth+5;
end;
DBGridName.DataSource.Dataset.EnableControls;
end;
dbgrid一列从头扫到尾,扫的过程中不断从当前行的这一列取出值赋给label.caption,并记录一列扫描过程的label.width的最大值
把最大值赋给dbgrid该列的width属性。
1.设AutoFitColWidths=true;
它的列宽会跟据整个Grid的宽度自动调整
且每一列(TColumnEh)都有AutoFitColWidth属性,设为true,该列宽度自动调整
2.OptionsEh中有dghDblClickOptimizeColWidth,当双击表缝时,前一列按当前数据宽度自动调整宽度(与Excel中功能相同)
你可以参看它的源码,看它如何实现的
var
i: integer;
TotWidth: integer; //定义整个宽度
VarWidth: integer; //定义变化的宽度
ResizableColumnCount: integer; //定义变化宽度列的总数
AColumn: TColumn;
begin //在重新调整前所有列的宽度 TotWidth := 0;
VarWidth := 0;//有多少列需要自动调整 ResizableColumnCount := 0;
for i := 0 to -1 + DBGrid.Columns.Count do
begin
TotWidth := TotWidth + DBGrid.Columns[i].Width;
if DBGrid.Columns[i].Field.Tag <> 0 then
Inc(ResizableColumnCount);
end;//为每个列分隔线增加1PX if dgColLines in DBGrid.Options then
TotWidth := TotWidth + DBGrid.Columns.Count;
if dgIndicator in DBGrid.Options then
VarWidth := DBGrid.ClientWidth - TotWidth;//平均分配变化宽度的值//给所有需要自动调整的列 if ResizableColumnCount > 0 then
VarWidth := varWidth div ResizableColumnCount;
for i := 0 to -1 + DBGrid.Columns.Count do
begin
AColumn := DBGrid.Columns[i];
if AColumn.Field.Tag <> 0 then
begin
AColumn.Width := AColumn.Width + VarWidth;
if AColumn.Width < AColumn.Field.Tag then
AColumn.Width := AColumn.Field.Tag;
end;
end;
end;
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
var
nDisplayWidth : integer;
begin
nDisplayWidth := TDBGrid(Sender).Canvas.TextWidth(Field.AsString) + 4;
if nDisplayWidth > TDBGrid(Sender).Columns.Items[Field.Index].Width then
TDBGrid(Sender).Columns.Items[Field.Index].Width := nDisplayWidth;
end;
DBGridEH
挺好用的说,哪里有该控件下载?
Dbgrideh1.Columns[i].OptimizeWidth;
//可以搞定打开后列宽为最小值,不必担心空白区域较大问题