搜索
查看: 6954|回复: 24

[扩展库] vlistview - Virtual List (虚表)

[复制链接]

33

主题

543

帖子

3304

积分

荣誉会员

Rank: 8Rank: 8

积分
3304
发表于 2014-3-13 22:33:05 | 显示全部楼层 |阅读模式
使用方法
将范例工程用户库下的文件夹拷贝到目标工程的用户库目录下。

Table Adapter
使用 table 作为数据源。
  1. var data = {
  2.     { "张三"; "男" };
  3.     { "李四"; "女" };
  4.     { "王五"; "男" };
  5. };

  6. mainForm.vlistview.setDataSource(data);
复制代码
可以在 setDataSource 的第二个参数中指定要使用的键名:
  1. var data = {
  2.     { id = "1"; name = "张三"; sex = "男" };
  3.     { id = "2"; name = "李四"; sex = "女" };
  4.     { id = "3"; name = "王五"; sex = "男" };
  5. };

  6. mainForm.vlistview.setDataSource(data, { "name"; "sex" });
复制代码

ADO RecordSet Adapter
使用 ADO 记录集作为数据源。记录集必须以静态游标方式打开。
  1. var rs = db.openRecordSet("SELECT * FROM homepage2", 3);
  2. mainForm.vlistview.setDataSource(rs);
复制代码

Class Adapter
使用自定义 class 作为数据源。类必须实现 rowCount 和 getItem 方法。
  1. mainForm.vlistview.setDataSource(class {
  2.     rowCount = function () {
  3.         return 1000;
  4.     }
  5.    
  6.     getItem = function (row, col) {
  7.         select col {
  8.             case 1
  9.                 return tostring(row);
  10.             case 2
  11.                 return tostring(..math.random(0, 100));
  12.         }
  13.     }
  14. });
复制代码

代码在线查看

http://share.aardiofans.com/content/view/52

范例工程
vlistview.7z (5.02 KB, 下载次数: 444)

评分

参与人数 4银币 +170 收起 理由
asdfasfaf + 30 很给力!
aaucn + 60 很给力!
CP3 + 50 很给力!
LMJ243 + 30 很给力!

查看全部评分

回复

使用道具 举报

2

主题

48

帖子

1192

积分

四级会员

Rank: 6Rank: 6

积分
1192
QQ
发表于 2014-3-13 23:50:34 | 显示全部楼层

感谢,支持!!非常有用的东西...

感谢,支持!!非常有用的东西...
一曲且为梦中人..
回复

使用道具 举报

26

主题

104

帖子

637

积分

荣誉会员

Rank: 8Rank: 8

积分
637
发表于 2014-3-14 00:11:17 | 显示全部楼层

感谢分享,前排支持,作为aardiofans, 很幸运论坛有lujjjh这样的牛人!

感谢分享,前排支持,作为aardiofans, 很幸运论坛有lujjjh这样的牛人!
回复

使用道具 举报

52

主题

1341

帖子

7331

积分

荣誉会员

Rank: 8Rank: 8

积分
7331
发表于 2014-3-14 00:43:57 | 显示全部楼层

非常实用的功能,感谢分享,学习~

非常实用的功能,感谢分享,学习~
回复

使用道具 举报

0

主题

12

帖子

77

积分

一级会员

Rank: 2

积分
77
发表于 2014-3-14 08:50:52 | 显示全部楼层

恩,真的很强大哦,感谢啊,支持!{:3_48:}

恩,真的很强大哦,感谢啊,支持!
回复

使用道具 举报

0

主题

9

帖子

112

积分

一级会员

Rank: 2

积分
112
发表于 2014-3-14 09:17:22 | 显示全部楼层

楼主真是大好人啊,学习了

楼主真是大好人啊,学习了
回复

使用道具 举报

5

主题

127

帖子

1372

积分

四级会员

Rank: 6Rank: 6

积分
1372
发表于 2014-3-14 10:14:54 | 显示全部楼层

又见大作,辛苦了。

又见大作,辛苦了。
回复

使用道具 举报

0

主题

10

帖子

198

积分

一级会员

Rank: 2

积分
198
QQ
发表于 2014-3-14 10:16:56 | 显示全部楼层

{:3_48:}

回复

使用道具 举报

4

主题

9

帖子

72

积分

一级会员

Rank: 2

积分
72
发表于 2014-3-14 21:09:47 | 显示全部楼层

请问赋值的数据,怎么在退出的时候保存呢。

请问赋值的数据,怎么在退出的时候保存呢。

点评

设法保存数据源的数据即可,这是虚表以外的东西了。  发表于 2014-3-14 21:12
回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-15 23:39:17 | 显示全部楼层

我以前也在listview中添加过记录集内容,不过是把记录集放到了一个table中,然后逐条add进去的。请教这个虚表具体在哪些方面或哪种场景下更加优秀,更便于

我以前也在listview中添加过记录集内容,不过是把记录集放到了一个table中,然后逐条add进去的。请教这个虚表具体在哪些方面或哪种场景下更加优秀,更便于使用呢?谢谢。
回复

使用道具 举报

33

主题

543

帖子

3304

积分

荣誉会员

Rank: 8Rank: 8

积分
3304
 楼主| 发表于 2014-3-16 10:59:59 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=65090&ptid=11729][c

lvjing79 发表于 2014-3-15 23:39
我以前也在listview中添加过记录集内容,不过是把记录集放到了一个table中,然后逐条add进去的。请教这个虚 ...

虚表的思想就是,不预先把所有数据放进去,而是“按需加载”。大数据量不考虑内存的话,光是压到 listview 里就要花费很多时间。

同样的思路还可以应用于显示大文件上。假设要写个二进制文件编辑器,把文件一次性读入内存肯定是不合适的,这时候可以根据滚动条的位置,把文件光标 seek 到指定的地方,读入能填满整个屏幕的数据就可以了。
回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-16 20:40:34 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=65096&ptid=11729][c

lujjjh 发表于 2014-3-16 10:59
虚表的思想就是,不预先把所有数据放进去,而是“按需加载”。大数据量不考虑内存的话,光是压到 listvie ...

受教了。例如我从数据库读取的数据有超过10万条,加载到listview里面基本是不可想象的。但是如果有虚表的话,应该可以。不知道lujjjh有没有对大容量进行过测试?我会好好研究一下这个东西,对我很有用。谢谢。
回复

使用道具 举报

151

主题

2375

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13058
发表于 2014-3-17 22:31:27 | 显示全部楼层

感谢lujjjh,做了一些小的改进添加到了扩展库,用法有些不同改名为win.ui.ctrl.vlist以示区别。 setDataSource() 分离成了各自

感谢lujjjh,做了一些小的改进添加到了扩展库,用法有些不同改名为win.ui.ctrl.vlist以示区别。
setDataSource() 分离成了各自独立的无关函数,例如 mainForm.vlist.createSqliteAdapter()
mainForm.vlist.createAdoAdapter() 等等,增加了sqlite数据源支持。

vlistCtrl.updateDataSource()函数改为  vlistCtrl.dataAdapter.update()
增加可自定的的 vlistCtrl.dataAdapter.close()  用于关闭数据连接,控件在切换数据源时将自动调用 close()函数。

去掉了getItem() 等不必要的跳转,以及其他一些小的改进。下面是用法示例:

sqlite数据源:
  1. import win.ui;
  2. import win.ui.ctrl.vlist;
  3. /*DSG{{*/
  4. mainForm = ..win.form(text="vlist - sqlite adapter";right=600;bottom=367)
  5. mainForm.add(
  6. vlist={cls="vlist";left=48;top=40;right=552;bottom=328;edge=1;transparent=1;z=1}
  7. )
  8. /*}}*/

  9. mainForm.vlist.insertColumn("网址", 200);
  10. mainForm.vlist.insertColumn("评论", 200);

  11. //启用双缓冲,避免拖动滚动条时闪烁
  12. mainForm.vlist.setExtended(0x10000/*_LVS_EX_DOUBLEBUFFER*/);

  13. import sqlite;
  14. var db = sqlite("/test.db");

  15. //创建测试数据
  16. if (!db.existsTable("homepage2")) {
  17.         db.exec("CREATE TABLE homepage2 (url char(30), comment char(20))");
  18.        
  19.         db.beginTrans()
  20.         for (i = 1; 1000) {
  21.                 db.exec("INSERT INTO homepage2(url, comment) VALUES(@url,@comment)", {
  22.                         url = "http://www.aardio.com";
  23.                         comment = "字符串包含'单引号' " ++ i;
  24.                 });
  25.         }
  26.         db.commitTrans()
  27. }

  28. //绑定数据源
  29. mainForm.vlist.createSqliteAdapter(db,"SELECT * FROM homepage2").close = function(){
  30.     db.close();
  31. };

  32. mainForm.show();
  33. win.loopMessage();  
复制代码

ADO数据源:
  1. import win.ui;
  2. import win.ui.ctrl.vlist;
  3. /*DSG{{*/
  4. mainForm = ..win.form(text="vlist - ADO RecordSet Adapter";right=600;bottom=367)
  5. mainForm.add(
  6. vlist={cls="vlist";left=48;top=40;right=552;bottom=328;edge=1;transparent=1;z=1}
  7. )
  8. /*}}*/

  9. mainForm.vlist.insertColumn("网址", 200);
  10. mainForm.vlist.insertColumn("评论", 200);

  11. //启用双缓冲,避免拖动滚动条时闪烁
  12. mainForm.vlist.setExtended(0x10000/*_LVS_EX_DOUBLEBUFFER*/);

  13. import access;

  14. //创建测试数据
  15. var db = access("/test.mdb");
  16. if (!db.existsTable("homepage2")) {
  17.         db.exec("CREATE TABLE homepage2 (url char(30), comment char(20))");
  18.        
  19.         db.connection.BeginTrans();
  20.         for (i = 1; 1000) {
  21.                 db.exec("INSERT INTO homepage2(url, comment) VALUES(@url,@comment)", {
  22.                         url = "http://www.aardio.com";
  23.                         comment = "字符串包含'单引号' " ++ i;
  24.                 });
  25.         }
  26.         db.connection.CommitTrans();
  27. }

  28. var rs = db.openRecordSet("SELECT * FROM homepage2", 3);
  29. mainForm.vlist.createAdoAdapter(rs).close = function(){
  30.     rs.close();
  31.     db.close();
  32. };

  33. mainForm.show();
  34. win.loopMessage();  
复制代码


显示图标:
  1. import win.ui;
  2. import win.ui.ctrl.vlist;
  3. /*DSG{{*/
  4. mainForm = ..win.form(text="vlist - Icon";right=607;bottom=367)
  5. mainForm.add(
  6. vlist={cls="vlist";left=48;top=40;right=552;bottom=328;edge=1;mode="icon";z=1}
  7. )
  8. /*}}*/

  9. import win.imageList;
  10. var imageList = win.imageList(32, 32);
  11. ::ImageList_ReplaceIcon(imageList, -1, ::LoadIcon(, topointer(0x7F00/*_IDI_APPLICATION*/)));
  12. mainForm.vlist.setImageList(imageList, 0/*_LVSIL_NORMAL*/);

  13. var data = table.array(100000, 2, { iImage = 0; text = "1.exe" });
  14. mainForm.vlist.createTableAdapter(data);

  15. mainForm.show();
  16. win.loopMessage();
复制代码


table数据源:
  1. import win.ui;
  2. import win.ui.ctrl.vlist;
  3. /*DSG{{*/
  4. mainForm = ..win.form(text="vlist - Table Adapter";right=600;bottom=400)
  5. mainForm.add(
  6. button={cls="button";text="更新";left=232;top=344;right=336;bottom=368;z=2};
  7. vlist={cls="vlist";left=48;top=40;right=552;bottom=328;edge=1;z=1}
  8. )
  9. /*}}*/

  10. mainForm.vlist.insertColumn("姓名", 200);
  11. mainForm.vlist.insertColumn("性别", 100);

  12. var data = {
  13.         { "张三"; "男" };
  14.         { "李四"; "女" };
  15.         { "王五"; "男" };
  16. };

  17. mainForm.vlist.createTableAdapter(data);

  18. mainForm.button.oncommand = function(id, event) {
  19.         data[2][2] = "男";
  20.         mainForm.vlist.dataAdapter.update()
  21. }

  22. mainForm.show();
  23. win.loopMessage();
复制代码


自定义数据:
  1. import win.ui;
  2. import win.ui.ctrl.vlist;
  3. /*DSG{{*/
  4. mainForm = ..win.form(text="vlist - Class Adapter";right=600;bottom=400)
  5. mainForm.add(
  6. button={cls="button";text="更新";left=232;top=344;right=336;bottom=368;z=2};
  7. vlist={cls="vlist";left=48;top=40;right=552;bottom=328;edge=1;transparent=1;z=1}
  8. )
  9. /*}}*/

  10. mainForm.vlist.insertColumn("ID", 80);
  11. mainForm.vlist.insertColumn("值", 100);

  12. mainForm.vlist.createAdapter( class {
  13.     count = function () {
  14.         return 10;
  15.     }  
  16.     getItem = function (row, col) {
  17.         return ..string.random(3);
  18.     }
  19.     close = function () {
  20.         
  21.     }
  22. });

  23. mainForm.button.oncommand = function(id, event) {
  24.         mainForm.vlist.dataAdapter.update()
  25. }

  26. mainForm.show();
  27. win.loopMessage();
复制代码


该扩展库需要用到新版提供的一些函数,使用前请先更新aardio。

评分

参与人数 3银币 +140 收起 理由
asdfasfaf + 30 赞一个!
CP3 + 50 很给力!
aaucn + 60 很给力!

查看全部评分

回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-27 15:07:06 | 显示全部楼层

我做了一下大数量测试,记录集有两个字段,记录条数为40万,能够正常显示,非常棒!

我做了一下大数量测试,记录集有两个字段,记录条数为40万,能够正常显示,非常棒!
回复

使用道具 举报

9

主题

463

帖子

2556

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2556
发表于 2014-3-27 15:32:45 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=65291&ptid=11729][c

lvjing79 发表于 2014-3-27 15:07
我做了一下大数量测试,记录集有两个字段,记录条数为40万,能够正常显示,非常棒!


虚表不是用来显示几十万的数据,这个你要去使用分页。
滚动条只有那么长跳一格listview那得刷新好几千下,不要说几十万,论坛几万的帖子放到一个虚表里显示都不可思议。
回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-27 22:50:42 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=65293&ptid=11729][c

roger 发表于 2014-3-27 15:32
虚表不是用来显示几十万的数据,这个你要去使用分页。
滚动条只有那么长跳一格listview那得刷新好几千 ...

明白,纯粹为了测试而已。实际使用不会这样,普通用户别说40万,400行他也没有耐心拖着看的,肯定得想其它办法,例如过滤等等。
回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-29 22:01:05 | 显示全部楼层

有一种场景一直没有想好怎么使用虚表。我有一个查询数据库的程序,允许用户查询时选择开始日期和结束日期,每个日期是一张表。程序循环查询开始到结束日期之间的每一天的表

有一种场景一直没有想好怎么使用虚表。我有一个查询数据库的程序,允许用户查询时选择开始日期和结束日期,每个日期是一张表。程序循环查询开始到结束日期之间的每一天的表,查到数据就插入到listview中。
如果用虚表,createAdoAdapter只能指定一个记录集。这样每查到一天的数据后都要重新绑定一次,那样原来listview中的数据就没有了。
如果用sql语句union完再获取查询记录集,当日期间隔太长时语句会非常长,这样也不是一个好的解决办法。
不知道各位有没有好的解决方案呢?谢谢。

点评

“每个日期是一张表”的做法就不妥。  发表于 2014-3-29 22:21
回复

使用道具 举报

7

主题

77

帖子

493

积分

二级会员

Rank: 3Rank: 3

积分
493
发表于 2014-3-30 22:52:21 | 显示全部楼层

[i=s] 本帖最后由 lvjing79 于 2014-3-31 09:08 编辑 [/i] [quote][size=2][url=forum.php?mo

本帖最后由 lvjing79 于 2014-3-31 09:08 编辑
lvjing79 发表于 2014-3-29 22:01
有一种场景一直没有想好怎么使用虚表。我有一个查询数据库的程序,允许用户查询时选择开始日期和结束日期, ...


每日一张表这个是客观所限,表的业务记录数每日超过300万条,不在一张表还真不行。只能在数据库方面想办法了。
回复

使用道具 举报

0

主题

1

帖子

12

积分

新手入门

Rank: 1

积分
12
发表于 2014-4-5 07:54:34 | 显示全部楼层

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=65359&ptid=11729][c

lvjing79 发表于 2014-3-30 22:52
每日一张表这个是客观所限,表的业务记录数每日超过300万条,不在一张表还真不行。只能在数据库方面想 ...

考虑一下分区表吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-4-23 08:00 , Processed in 0.093750 second(s), 34 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表