为什么ListView1.Items.Insert(0)后新插入的ListItem没有显示在应有的位置?

ooolinux 2021-01-04 08:26:31
为什么ListView1.Items.Insert(0)后新插入的ListItem没有显示在应有的位置?
测试代码如下:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
this->ListView1->ViewStyle=vsIcon;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TListItem *li;
for(int i=1;i<=3;++i)
{
li=this->ListView1->Items->Add();
li->Caption=L"add"+IntToStr(i);
}
li=this->ListView1->Items->Insert(0);
li->Caption=L"insert0";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListView1Click(TObject *Sender)
{
this->Caption=IntToStr(this->ListView1->ItemIndex);
}
//---------------------------------------------------------------------------
...全文
692 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2021-01-20
  • 打赏
  • 举报
回复
引用 21 楼 早打大打打核战争的回复:
应该是xerox,施乐和苹果也是最早搞unicode的,早期unicode只是商业设计,还没有合并到ISO标准中
施乐公司,在中国不是很有名。
  • 打赏
  • 举报
回复
应该是xerox,施乐和苹果也是最早搞unicode的,早期unicode只是商业设计,还没有合并到ISO标准中
ooolinux 2021-01-20
  • 打赏
  • 举报
回复
引用 23 楼 早打大打打核战争的回复:
[quote=引用 22 楼 ooolinux 的回复:][quote=引用 21 楼 早打大打打核战争的回复:]应该是xerox,施乐和苹果也是最早搞unicode的,早期unicode只是商业设计,还没有合并到ISO标准中

施乐公司,在中国不是很有名。[/quote]

据说是复印机和激光打印机的发明者
[/quote] 有创新,有技术的企业,技术>商业。
  • 打赏
  • 举报
回复
引用 22 楼 ooolinux 的回复:
[quote=引用 21 楼 早打大打打核战争的回复:]应该是xerox,施乐和苹果也是最早搞unicode的,早期unicode只是商业设计,还没有合并到ISO标准中

施乐公司,在中国不是很有名。[/quote]

据说是复印机和激光打印机的发明者
  • 打赏
  • 举报
回复
引用 15 楼 ooolinux 的回复:
[quote=引用 14 楼 早打大打打核战争的回复:]难道是因为图标的问题,不显示图标的vsList、vsReport模式都是正常的

技术上不是做不到,可能要考虑到16位Windows的电脑配置了。[/quote]

可能是早期windows中的设计遗留的问题,后来也就一直兼容下来了。我记得很早以前曾经看到过文章说早期windows中的GDI默认只建立5个DC给所有程序共用,如果程序不自己CreateDC的话,因为DC是一个很大的结构,大概有几百字节。不禁有点佩服微软,面向过程的程序设计方法,居然也能写出windows这么复杂的软件。
墨梅无痕 2021-01-19
  • 打赏
  • 举报
回复
在 vsIcon 和 vsSmallIcon 条件下插入、删除内容,涉及到图标重绘的效率问题,所以请使用 TListItem.BeginUpdate 和 TListItem.EndUpdate 来操作。
ooolinux 2021-01-19
  • 打赏
  • 举报
回复
引用 17 楼 早打大打打核战争 的回复:
[quote=引用 15 楼 ooolinux 的回复:][quote=引用 14 楼 早打大打打核战争的回复:]难道是因为图标的问题,不显示图标的vsList、vsReport模式都是正常的

技术上不是做不到,可能要考虑到16位Windows的电脑配置了。[/quote]

可能是早期windows中的设计遗留的问题,后来也就一直兼容下来了。我记得很早以前曾经看到过文章说早期windows中的GDI默认只建立5个DC给所有程序共用,如果程序不自己CreateDC的话,因为DC是一个很大的结构,大概有几百字节。不禁有点佩服微软,面向过程的程序设计方法,居然也能写出windows这么复杂的软件。
[/quote]
Windows也从苹果那里学习了,GUI更早好像是一家打印机公司(记不清了)的演示产品,带一个原始的鼠标。
ooolinux 2021-01-19
  • 打赏
  • 举报
回复
引用 17 楼 早打大打打核战争 的回复:
[quote=引用 15 楼 ooolinux 的回复:][quote=引用 14 楼 早打大打打核战争的回复:]难道是因为图标的问题,不显示图标的vsList、vsReport模式都是正常的

技术上不是做不到,可能要考虑到16位Windows的电脑配置了。[/quote]

可能是早期windows中的设计遗留的问题,后来也就一直兼容下来了。我记得很早以前曾经看到过文章说早期windows中的GDI默认只建立5个DC给所有程序共用,如果程序不自己CreateDC的话,因为DC是一个很大的结构,大概有几百字节。不禁有点佩服微软,面向过程的程序设计方法,居然也能写出windows这么复杂的软件。
[/quote]
Windows 1.0的时候可能内存只有1、2M。
ooolinux 2021-01-19
  • 打赏
  • 举报
回复
引用 16 楼 墨梅无痕 的回复:
在 vsIcon 和 vsSmallIcon 条件下插入、删除内容,涉及到图标重绘的效率问题,所以请使用 TListItem.BeginUpdate 和 TListItem.EndUpdate 来操作。

TListItems 吧
ooolinux 2021-01-15
  • 打赏
  • 举报
回复
引用 14 楼 早打大打打核战争的回复:
难道是因为图标的问题,不显示图标的vsList、vsReport模式都是正常的
技术上不是做不到,可能要考虑到16位Windows的电脑配置了。
  • 打赏
  • 举报
回复
难道是因为图标的问题,不显示图标的vsList、vsReport模式都是正常的
ooolinux 2021-01-14
  • 打赏
  • 举报
回复
引用 12 楼 imisewer 的回复:
一直用vsReport模式的,一直没遇到过这个问题。。。。

不知道微软为什么这么做,不同模式区别对待
imisewer 2021-01-14
  • 打赏
  • 举报
回复
一直用vsReport模式的,一直没遇到过这个问题。。。。
ooolinux 2021-01-07
  • 打赏
  • 举报
回复
引用 10 楼 早打大打打核战争 的回复:
ViewStyle设置成vsList就是正常的

和vsIcon的表现不一致,不知道是微软的问题,还是VCL封装的问题。
  • 打赏
  • 举报
回复
ViewStyle设置成vsList就是正常的
ooolinux 2021-01-06
  • 打赏
  • 举报
回复
引用 8 楼 早打大打打核战争 的回复:
没有研究这个问题,可能跟listview内部存储的数据结构有关,也许用的是数组,不是链表?

搞不懂微软怎么弄的。
  • 打赏
  • 举报
回复
没有研究这个问题,可能跟listview内部存储的数据结构有关,也许用的是数组,不是链表?
ooolinux 2021-01-06
  • 打赏
  • 举报
回复
我发现删除一项也会留个空位置,不会自动排列图标。应该跟这个也有关。
ooolinux 2021-01-05
  • 打赏
  • 举报
回复
引用 3 楼 tanqth的回复:

var
  I:Integer;
  vt:TListItem;
begin
  ListView1.Items.BeginUpdate;
  for I := 1 to 4 do
  begin
    vt:=ListView1.Items.Add ;
    vt.Caption:='t'+i.ToString;
  end;
  vt:=ListView1.Items.Insert(0);
  vt.Caption:='0000';
  ListView1.Items.EndUpdate;
加上BeginUpdate与EndUpdate,是可以的。
主要是,需要在不同的时间添加和插入项目。
tanqth 2021-01-05
  • 打赏
  • 举报
回复

var
  I:Integer;
  vt:TListItem;
begin
  ListView1.Items.BeginUpdate;
  for I := 1 to 4 do
  begin
    vt:=ListView1.Items.Add ;
    vt.Caption:='t'+i.ToString;
  end;
  vt:=ListView1.Items.Insert(0);
  vt.Caption:='0000';
  ListView1.Items.EndUpdate;
加上BeginUpdate与EndUpdate,是可以的。
加载更多回复(4)
Delphi ListView基本用法大全(转)默认分类 2009-09-29 09:27:56 阅读138 评论0 字号:大中小 订阅 Delphi高级编程 Delphi文章 WEB开发 Delphi控件 Delphi ListView基本用法大全 作者:seeker 日期:2009-04-19 //增加项或列(字段) ListView1.Clear; ListView1.Columns.Clear; ListView1.Columns.Add; ListView1.Columns.Add; ListView1.Columns.Add; ListView1.Columns.Items[0].Caption:='id'; ListView1.Columns.Items[1].Caption:='type'; ListView1.Columns.Items[2].Caption:='title'; ListView1.Columns.Items[2].Width:=300; Listview1.ViewStyle:=vsreport; Listview1.GridLines:=true; //注:此处代码也可以直接在可视化编辑器中完成, 也可写成以下这样 begin with listview1 do begin Columns.Add; Columns.Add; Columns.Add; ViewStyle:=vsreport; GridLines:=true; columns.items[0].caption:='进程名'; columns.items[1].caption:='进程ID'; columns.items[2].caption:='进程文件路径'; Columns.Items[0].Width:=100; Columns.Items[1].Width:=100; Columns.Items[2].Width:=150; end end; //增加记录 with listview1.items.add do begin caption:='1212'; subitems.add('hh1'); subitems.add('hh2'); end; //删除 listview1.items.delete(0); //从数据库表里读取数据写入Listview var Titem:Tlistitem; //此处一定要预定义临时记录存储变量. begin ListView1.Items.Clear; with adoquery1 do begin close; sql.Clear; sql.Add('select spmc,jg,sl from kcxs'); Open; ListView1.Items.Clear; while not eof do begin Titem:=ListView1.Items.add; Titem.Caption:=FieldByName('spmc').Value; Titem.SubItems.Add(FieldByName('sl').Value); Titem.SubItems.Add(FieldByName('jg').Value); next; end; //删除 ListView1.DeleteSelected; //如何取得ListView中选中行的某一列的值 procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage(ListView1.Selected.SubItems.Strings[1]); //返回选中行第三列中的值 end; showMessage(listView1.Selected.Caption); //返回选中行第一列的值. 第1列的值: -->>> ListView1.Selected.Caption 第i列的值(i>1):-->>> ListView1.Selected.SubItems.Strings[i] ListView1.Items.Item[1].SubItems.GetText); //取得listview某行某列的值 Edit2.Text := listview1.Items[i].SubItems.strings[0]; //读第i行第2列 返回选中行所有子列值.是以回车符分开的,你还要从中剥离出来你要的子列的值。 showMessage(ListView1.Selected.SubItems.GetText); ListView 简单排序的实现 ListView 排序 怎样实现单击一下按升序,再单击一下按降序。 function CustomSortProc(Item1, Item2: TListItem; ColumnIndex: integer): integer; stdcall; begin if ColumnIndex = 0 then Result := CompareText(Item1.Caption,Item2.Caption) else Result := CompareText(Item1.SubItems[ColumnIndex-1],Item2.SubItems[ColumnIndex-1]) end; procedure TFrmSrvrMain.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin ListView1.CustomSort(@CustomSortProc,Column.Index); end; =============================================================== //增加 i := ListView1.Items.Count; with ListView1 do begin ListItem:=Items.Add; ListItem.Caption:= IntToStr(i); ListItem.SubItems.Add('第 '+IntToStr(i)+' 行'); ListItem.SubItems.Add('第三列内容'); end; //按标题删除 for i:=ListView1.Items.Count-1 downto 0 Do if ListView1.Items[i].Caption = Edit1.Text then begin ListView1.Items.Item[i].Delete(); //删除当前选中行 end; //选中一行 if ListView1.Selected <> nil then Edit1.Text := ListView1.Selected.Caption; // listview1.Items[Listview1.Items.Count -1].Selected := True; // listview1.Items[Listview1.Items.Count -1].MakeVisible(True); procedure TForm1.Button2Click(Sender: TObject); // 选择第一条 begin listview1.SetFocus; listview1.Items[0].Selected := True; end; procedure TForm1.Button1Click(Sender: TObject); // 选择最后一条 begin listview1.SetFocus; listview1.Items[Listview1.Items.Count -1].Selected := True; end; //这是个通用的过程 procedure ListViewItemMoveUpDown(lv : TListView; Item : TListItem; MoveUp, SetFocus : Boolean); var DestItem : TListItem; begin if (Item = nil) or ((Item.Index - 1 < 0) and MoveUp) or ((Item.Index + 1 >= lv.Items.Count) and (not MoveUp)) then Exit; lv.Items.BeginUpdate; try if MoveUp then DestItem := lv.Items.Insert(Item.Index - 1) else DestItem := lv.Items.Insert(Item.Index + 2); DestItem.Assign(Item); lv.Selected := DestItem; Item.Free; finally lv.Items.EndUpdate; end; if SetFocus then lv.SetFocus; DestItem.MakeVisible(False); end; //此为调用过程,可以任意指定要移动的Item,下面是当前(Selected)Item ListViewItemMoveUpDown(ListView1, ListView1.Selected, True, True);//上移 ListViewItemMoveUpDown(ListView1, ListView1.Selected, False, True);//下移 TListView组件使用方法 引用CommCtrl单元 procedure TForm1.Button1Click(Sender: TObject); begin ListView_DeleteColumn(MyListView.Handle, i);//i是要删除的列的序号,从0开始 end; 用LISTVIEW显示表中的信息: procedure viewchange(listv:tlistview;table:tcustomadodataset;var i:integer); begin tlistview(listv).Items.BeginUpdate; {listv:listview名} try tlistview(listv).Items.Clear; with table do {table or query名} begin active:=true; first; while not eof do begin listitem:=tlistview(listv).Items.add; listitem.Caption:=trim(table.fields[i].asstring); // listitem.ImageIndex:=8; next; end; end; finally tlistview(listv).Items.EndUpdate; end; end; ListView使用中的一些要点。以下以一个两列的ListView为例。 →增加一行: with ListView1 do begin ListItem:=Items.Add; ListItem.Caption:='第一列内容'; ListItem.SubItems.Add('第二列内容'); end; →清空ListView1: ListView1.Items.Clear; →得到当前被选中行的行的行号以及删除当前行: For i:=0 to ListView1.Items.Count-1 Do If ListView1.Items[i].Selected then //i=ListView1.Selected.index begin ListView1.Items.Delete(i); //删除当前选中行 end; 当然,ListView有OnSelectItem事件,可以判断选择了哪行,用个全局变量把它赋值出来。 →读某行某列的操作: Edit1.Text := listview1.Items[i].Caption; //读第i行第1列 Edit2.Text := listview1.Items[i].SubItems.strings[0]; //读第i行第2列 Edit3.Text := listview1.Items[i].SubItems.strings[1]; //读第i行第3列 以次类推,可以用循环读出整列。 →将焦点上移一行: For i:=0 to ListView1.Items.Count-1 Do If (ListView1.Items[i].Selected) and (i>0) then begin ListView1.SetFocus; ListView1.Items.Item[i-1].Selected := True; end; 不过在Delphi6中,ListView多了一个ItemIndex属性,所以只要 ListView1.SetFocus; ListView1.ItemIndex:=3; 就能设定焦点了。 Delphi的listview能实现交替颜色么? procedure TForm1.ListView1CustomDrawItem( Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); var i: integer; begin i:= (Sender as TListView).Items.IndexOf(Item); if odd(i) then sender.Canvas.Brush.Color:= $02E0F0D7 else sender.Canvas.Brush.Color:= $02F0EED7; Sender.Canvas.FillRect(Item.DisplayRect(drIcon)); end; 要想随时更改ListView 中某一行的字体颜色,要在ListView的 OnCustomDrawItem 的事件中书写相关的代码。例如 我想更改选中的某行字体的颜色,则需要在事件中写入下的代码: if item.Index = strtoint(edit1.Text) then //该条件是用于判断是否符合更改字体颜色的行的条件。 Sender.Canvas.Font.Color := clred;

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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