如何使ListBox的每一个Item与一整型数据关联起来?(100分)

  • 主题发起人 主题发起人 dev2
  • 开始时间 开始时间
D

dev2

Unregistered / Unconfirmed
GUEST, unregistred user!
需求详细描述:
在往ListBox加Item时(如UserName),希望该Item与一个整型数据如(UserID)
关联起来,以便用户点击Item时,不用再根据选择的Item内容去查找数据库,才能
获取对应的UserID。而是用ListBox的某一方法取回关联的数据。
相关信息:
1。VC中ListBox数据关联实现是使用:
CListBox::SetItemData(int nIndex; DWORD dwItemData);
数据获取现是使用:
CListBox::GetItemData(int nIndex; DWORD dwItemData);
2。Delphi中的类TcustcomListBox中有一Protected的方法:
SetItemData(Index: Integer; Adata: LongInt):dyamic;
GetItemData(Index: Integer; Adata: LongInt):dyamic;
3。TlistBox是由TcustcomListBox继承下来的
4。TlistBox没有将SetItemData方法Public,所以不能调用

请各位尽情亮招!!!
 
Subject更正:如何使ListBox的每一个Item分别与对应的整型数据关联起来?
 
dblookuplistbox
 
解决方法有两种:
1、创建一个TStringList的对象,其中的Names对应ListBox的Item
Values对应userid。
当选择了ListBox中的一条时,根据ItemIndex在TStringList中找到相应的Value值。
2、声明一个类,其中有userid属性,在ListBox的每一个Item的Data中都带有一个该类的实例
 
谢谢两位同道的指点。
可VC中的CListBox::SetItemData(int nIndex; DWORD dwItemData);
CListBox::GetItemData(int nIndex; DWORD dwItemData);
简洁明了的用法,Delphi中如何使用呢?
讨论拓展:
1。如何使TreeView的每一个Item分别与对应的整型数据关联起来?
中元兄的招法在此就未能施展,请勿见怪。
刘兄可还有更美妙的方法?

2。VC中TreeView也是用SetItemData、GetItemData关联

再请出招......

 
呵呵,我特别懒,前几天写程序遇到这个问题找了个1stclass装上。
或者你看看1stclass的源代码?
 
小第在这拜见江湖各大门派的大师:
请给点练功心法,以解小第长期之困,
更免于走火入魔。

 
建议你使用指针;
type
PMyrecord=^TMyrecord;
TMyrecord=record
useid:integer;
..
..
end;
var arecord:pmyrecord;

new(arcord);
arcord^.useid:=2;
listbox.Items.AddObject(text,Tobject(arecord));
注意不需要时free
 
对于TreeView照样可以采用这两种方法
具体示例如下:

1、用TStringList

FList: TStringList;
//为TreeView和FList赋值部分略

在TreeView的Click事件中:
var
lStr: string;
userid: string;
begin
if TreeView.Selected = nil then Exit;
lStr := TreeView.Selected.Text;
userid := FList.Values[lStr];
end;

2、用类

事先声明一个含有userid的类 TTest
在加载TreeView时,采用AddObject()的方法,将对应的对象赋到Item的Data中在TreeView的Click事件中:
var
lTest: TTest;
userid: string;
begin
if TreeView.Selected = nil then Exit;
lTest := TreeView.Selected.Data;
userid := lTest.userid;
end;

 
怎么搞得这么复杂?



用addobject(string,pointer)一类的函数就可以实现vc内的setitemdata的功能

差别在于后者给对于的item一个相应的整数,前者给一个关联的指针,其实他们是一回事
因为:
———— 整数和指针一样,都是占四个byte内存。

可以

var
p : ^integer ;
i : integer ;//要关联的整数
begin
i := yourvalue ;
new(p);p^ := i ;
listbox1.items.addobject("string",p) ;// 记得在合适的时候,如系统退出时释放阿!
end

 
sanres兄:
且慢!
请注意,需求是: 每一个Item分别与对应的整型数据关联起来。
若Item总数为200,便得New200个指针,然后在不用时free?
还是刘兄内力较显深厚,出招更准!
还有那个门派深得Delphi真经,请稍露一二......
 
不过sanrex兄的剑法甚是凌厉!
望再出一招......
 
he,还在啊,说话有意思


>>>若Item总数为200,便得New200个指针,然后在不用时free?
有什么问题呢? 200X4= 800X8=6400bit不会内存那么惨吧?

用整数的消耗肯定对用类的小的多。200也没关系,有循环啊,何况这个对其他方法也
存在这个问题。
 
有些下文没贴上。。。

实际上,delphi内部的实现和vc一对比,就可以知道它肯定是通过整数和指针的特殊关系
高出来的。
我们观察 windows sdk --> vc --> delphi 的封装,还是很有规律的。sdk和vc
大量的使用整数对应对象,如handle,通过整数关联对象,如setitemdata内的整数
而delphi就利用整数和指针的特殊关系,直接用对象本身来关联,更高级了。
vc里也经常由这种情况,但以整数为准,要对象就要强制转换,delphi刚好相反,有整数
就要强制转换,要对象?不用转换,直接使用就可以了,转换也是对象间的转换。

胡说一大队,不知对你有什么用处没有?






 
高手过招,让吾辈见识不少
 
小第查了Delphi真经(类代码),发现:

1。AddObject()实际上是调用PutObject,而PutObject则调用SetItemData
2。listbox中函数声明:
listbox.Items.AddObject(Const s: String; AObject: TObject);Integer;Virtual;
3。TreeView中函数声明:
TreeView.Items.AddObject(Node: TTreeNode; Const s: String;; Ptr: Pointer):TTreeNode;

问题:
1。在表User中,UserID为主关键字,UserName则不是,这意味着UserName可重复。如此,
用TStringList方法会有麻烦,因为FList.Values[lStr]是根据UserName找到UserID的

2。用刘兄的第二种方法取回关联的数据确实方便实用,然对于ListBox、ComboBox又该如何实现呢?
且如何循环增加Item?

3。用sanrex兄的方法如何循环增加Item,200个指针变量如何管理以及如何取回关联的数据?
根据指针变量名?

唉!小第真是烦人.......



 

treeview和listbox,combox我都用过,给你个伪代码

描述: 随时同步数据库和listbox的显示
type
pint = ^interger ;
procedure Refresh_listbox_db
var
tempi : pint ;
begin
// 释放上次创建的指针
for i := 0 to listbox1.items.count -1 do
begin
dispose(Pint(listbox1.objects[0]));
listbox1.items.delete(0);
end;
while not table1.eof do
begin
new(tempi);
listbox1.Addobject(table1.Fieldbyname ('userid') , table1.Fieldbyname ('username');
table1.next ;
end;
end;

__________________________________________
取关联数据
lookup_data_by_listbox_itemindex (listbox1.itemindex );
var
temppi : pint ;i : integer ;
begin
temppi = pint(listbox.objects[itemindex]);
i = temppi^ ;
table1.locate("userid" ,i);
return curr_record ; 这就是你的关联数据
end;
__________________________________________
在系统退出时调用
procedure onclose
begin
for i := 0 to listbox1.items.count -1 do
begin
dispose(Pint(listbox1.objects));
end;
end;
 
>用sanrex兄的方法如何循环增加Item,200个指针变量如何管理以及如何取回关联的数据?
根据指针变量名?
不用那么麻烦吧,用上200个变量。定义一个数组就行了

var
A : array[0..9] of Integer;
I: Integer;
begin
for I:=0 to 9 do
begin
A:=I;
ListBox1.Items.AddObject('grp'+IntToStr(I),Tobject(a));
end;

//取回Item对应的整数 ,用
Integer(ListBox1.Items.Objects);就行了
end;
 
ListBox的问题已解决,方法如下(Code已调试通过):

数据关联:

User.first;
while not User.Eof do
begin
ListBox1.Items.AddObject(User.FieldByName('UserName').asString,
TObject(User.FieldByName('UserID').asInteger);
User.Next;
end;

{-----------------------------------------------}
数据获取:

Procedure TForm1.ListBox1Click(Sender: TObject);
Var
UserID: Integer;
Begin
with ListBox1 do
begin
UserID := Integer(Items.Object(ItemIndex)); // 数据获取:
.
.
.
end;
end;

{*******ComboBox同理***********}


问题:

1.以上Code是否需要释放Object对象(调试中发现内存好象愈来愈少,如何?)?
2.ListView无AddObject方法,如何关联呢?
3.谁可提供详细源代码(ListView、TreeView的,包括数据循环增加和关联,
数据获取、指针或对象的释放)


也许开发数据的较多的朋友会遇到相关问题, 小第垦望您的出手......



来到此地的时间虽不很长,然却渐渐喜欢且有一丝留恋起来。喜欢大家的
施援之手,留恋互暖的氛围。小第就此谢过各位!


秋风清
秋月明
落叶聚还散
寒鸦栖复惊
相思相见知何日
......

-------------------------------- n年再聚








 
1. 不需要,要释放的是指针的指向数据,而不是指针本身(他只是类似一个普通变量)
内存边少是其他的原因,我开始调试时也曾由此疑虑
2。listitem.data 就是你要的listveiw指针,treeview.treenode.data 同理
2。我想代码前面已经有了,treeview.listview.listbox,combobox 道理都是一样

 
后退
顶部