我遇到了在Delphi XE4(在Windows 7环境中)动态调整TJVListview列宽的问题。如果列表视图中存在大量数据,则应用程序需要较长的时间进行列调整大小,有时会引发访问冲突。我们使用以下代码来调整列的大小。
for i := 0 to LV.Columns.Count -1 do
begin
if LV.Columns.Items[i].Tag = 0 then
begin
LV.Columns.Items[i].Width := ColumnTextWidth;
LV.Columns.Items[i].Width := ColumnHeaderWidth;
end;
end;
以前使用相同的代码可以在Delphi 2009中正常工作。只有在我们使用customdrawitem事件时才会注意到这个问题(我们将图像放在listview中)。对于仅显示文本的普通列表视图,上面的代码工作正常。
我尝试使用Column AutoSize属性设置为true,但它没用。
有关如何克服此问题的任何建议。实际上,我们在应用程序中的多个位置使用了TJVlistview组件。
此致 希兰。
cODE:
1)在我的表单中,我有一个JVListview,Button和imagelist。用于加载到列表视图的按钮。 2)在Advancecustomdrawitem中,我尝试放置BMP控件并执行替代行颜色更改...
procedure TForm1.Button1Click(Sender: TObject);
var
i, ii: Integer;
ListItem: TListItem;
strVal : String;
begin
strVal := 'Test String';
try
ListView.Items.BeginUpdate;
LockWindowUpdate(listview.handle);
try
ListView.Clear;
for i := 1 to 15 do
begin
ListItem := ListView.Items.Add;
ListItem.SubItems.Add(strVal +'_' +IntToStr(i));
ListItem.SubItems.Add(strVal +'_' +IntToStr(i));
ListItem.SubItems.Add(strVal +'_' +IntToStr(i));
ListItem.SubItems.Add(strVal +'_' +IntToStr(i));
ListItem.SubItems.Add(strVal +'_' +IntToStr(i));
end;
finally
// for resizing the columns based on the text size
FitToTextWidth(ListView);
ListView.Items.EndUpdate;
LockWindowUpdate(0);
end;
except
on E: Exception do
MessageDlg(PWideChar(E.Message), TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
end;
end;
procedure TForm1.FitToTextWidth(LV: TListView);
var
i : integer;
begin
// Set the Column width based on based on textwidth and headerwidth
for i := 0 to LV.Columns.Count -1 do
begin
if LV.Columns.Items[i].Tag = 0 then
begin
LV.Columns.Items[i].Width := ColumnTextWidth;
LV.Columns.Items[i].Width := ColumnHeaderWidth;
end;
end;
end;
procedure TForm1.LISTVIEWAdvancedCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
var DefaultDraw: Boolean);
Var
R : TRect;
C : TCanvas;
B : TBitMap;
begin
// Set C
C := (Sender as TListView).Canvas;
// Set R
R := Item.DisplayRect(drLabel);
B := TBitMap.Create;
B.Transparent := True;
B.TransparentColor := clWhite;
// based on item index set the image and change the row color
if odd(item.Index) = true then
begin
ImageList.GetBitmap(0,B);
TJvListItem( Item ).Brush.Color := clWhite;
TJvListItem( Item ).Font.Color := clBlack;
end
else
begin
ImageList.GetBitmap(1,B);
TJvListItem( Item ).Brush.Color := clMoneyGreen;
TJvListItem( Item ).Font.Color := clBlack;
end;
C.Draw(R.Left + 5 ,R.Top, B);
B.Free;
end;
以上代码适用于Delphi 2009 ...但目前正在尝试在Win 7环境中迁移到XE4 ..我的问题是,加载列表视图需要大量时间(通过调用FitToTextWidth动态执行列调整大小时)方法)..但没有这种方法它工作正常,但没有列调整大小......
答案 0 :(得分:1)
当您将列的宽度设置为任何一个自动常量时,控件必须评估项目/子项目的长度,以便能够计算所需的宽度。这需要时间。
此外,当您设置列的宽度时,VCL ListView会更新所有列。
您有六列,设置其中任何一列的宽度涉及6列更新,以及FitToTextWidth
过程中的虚假调用,您的代码导致读取列的所有项目/子项42次(由于VCL中的代码路径:第一列的1次,第二次的2次 - >设置6列的宽度的21次)。将您的宽度设置包含在Begin / EndUpdate调用中并删除额外的调用,您将在6轮中完成它。
procedure TForm1.FitToTextWidth(LV: TListView);
var
i : integer;
begin
// Set the Column width based on based on textwidth and headerwidth
LV.Columns.BeginUpdate;
try
for i := 0 to LV.Columns.Count -1 do
begin
if LV.Columns.Items[i].Tag = 0 then
begin
// LV.Columns.Items[i].Width := ColumnTextWidth;
LV.Columns.Items[i].Width := ColumnHeaderWidth;
end;
end;
finally
LV.Columns.EndUpdate;
end;
end;
由于我的测试用例没有任何AV,我无法对此发表评论。