QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 8978|回复: 0
打印 上一主题 下一主题

在C++Builder中实现ListView的列标头点击排序功能

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
% M+ {8 v2 _7 y! N, J, \! p<>  </P>
; R" a2 Y" |" I3 |  Y<>天津大学电子与信息工程学院 </P>: m% X9 w* ^% r5 f; E3 \" _
<>宋天宁 </P>
: P( ~6 I% F7 V  B2 q  Z! w4 i+ f* j# j<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
2 U5 Z0 z# D8 e" n  w<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
9 X+ M7 s" z' k% h- [$ K1 {' n<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>4 A* h! B% E& {" O( y
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
2 x# L4 S, w8 x( a& q) a<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>" m1 N6 a( J+ T9 B' I( C3 a) u- s+ s
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>/ O( f' ^4 \% b( z- k& n
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
6 a5 E7 v' S4 y7 g<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>; Z% P; S' ~% c+ D+ a4 E
<>写自己的代码以完成这一功能。 </P>4 t: U& _% a; L
<>  </P>3 d$ `+ M: _* ~0 f
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
" N) w  {8 z% r$ ~+ i  [<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>/ T6 j0 R. u6 U, ~
<>内容以升序排列。 </P>
% `" D5 K5 P, e/ A8 j<>  </P>
2 R- J( h2 c. v7 i8 {<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
& W7 s* Q( ?$ D2 A. F4 C<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>! Z( v1 z& ^8 ^! n1 n
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
( y' N  F  I$ p3 |" v2 @<>包含子列和主列上的内容)。 </P>6 `2 j  r7 S, H8 f1 A
<>  </P>+ g; }; }2 Y+ a5 V6 U
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
$ M$ e- E3 s' c- N<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P># F- r" {) l" Q" T& E
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>  d/ v3 Q( M6 V, l) D. x" U
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
6 K; J* v' U( n9 N# e! v4 p<>  </P>
, P+ J9 \5 t7 M<>  </P>
2 b; T7 s5 f! e<>void __fastcall TForm1:istView1ColumnClick </P>
& Z. r# d2 v' F$ ^9 b<P>(TObject *Sender, </P>. G- o) p. v! a0 t
<P>TListColumn *Column) </P>
1 _# B0 h% F% k* K/ L<P>  </P>
: i; j, X' h4 H/ p% a4 B- m<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
  |; y' I" G! X, j; {; r- f- D<P>点击的列的信息。 </P>
# K5 _; }: p3 _7 S) J<P>---- 下面先定义变量: </P>
8 q* f% K9 R% j$ J1 @# t* C" ^<P>  </P>
, ]4 e/ a0 t4 X, w# G. `" R<P>int i,m,n,j; </P>
0 S3 k* E1 ?+ @, G0 z6 x, l<P>static bool od=true; </P>
2 V, t, s: O3 _9 P! r. A. _<P>od=!od; </P>
$ }! k. X& i: f/ m<P>  </P>
0 Z1 s1 P! @. f3 Q* x<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>$ I2 F4 u- R3 f) z% Z
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
* f* z% ]: N! [" X; ?% P<P>列表框中的总项目数。 </P>$ s6 V) c$ B. ^( E( X5 H
<P>n=Column- &gt;Index; </P>
6 S' \1 e1 k9 q/ o# [<P>m=ListView1- &gt;Items- &gt;Count; </P>& @/ p6 D+ Y) [& B3 a- X* a$ `/ A
<P>  </P>3 o8 \* A& O( c9 \8 v
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>1 c$ c3 Y& {/ Y  z4 g- `8 Q* I
<P>ListView1- &gt;Items- &gt;Add(); </P>- [2 E  b- L; q6 q% ~
<P>  </P>7 F7 w/ X! J7 ^( \: _
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
0 S. u* [& ]& i. u( j5 U4 f<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>% }- q" U4 b. z$ ?
<P>if (n==0) </P>
  l' q8 d- \9 P: P$ i<P>{ </P>$ v1 u& E9 k8 \0 }: C5 O/ {" f
<P>for(i=0;i&lt; m-1;i++) </P>8 l6 R0 t& n  D2 o- c5 @" y
<P>for(j=i+1;j&lt; m;j++) </P>
% D2 E& l, B8 X1 I3 j: n6 Y<P>if(od) </P>
; R' P1 |5 Q1 o; n% Y: g1 ~<P>{ </P>- E: [) b+ |% e4 w! K  M
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>- Z: H6 }, C; c$ B+ V
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>- x) S% `0 a! c- m) [4 I
<P>{ </P>
/ j- V. \& @: @/ I: j<P>ListView1- &gt;Items- &gt;Item[m]= </P>0 `+ }$ V1 y/ j- s" F
<P>ListView1- &gt;Items- &gt;Item; </P>  G! F, `5 y/ `' \" Z: Y- ?
<P>ListView1- &gt;Items- &gt;Item= </P>5 L0 A8 b. F2 u2 C: _/ b3 f: s% B- n' l- h
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
5 O) M# t& ?  J<P>ListView1- &gt;Items- &gt;Item[j]= </P>
# H7 n7 {6 v; O% l; m1 t<P>ListView1- &gt;Items- &gt;Item[m]; </P>+ F& O7 S" _; K3 O+ d1 h3 Q7 L9 m
<P>} </P>
2 O& J" a' d. n7 q2 N<P>} </P>3 j' R( E7 x3 H' m
<P>else </P>( |4 ~1 p, v- @4 y# i
<P>{ </P>' A8 \9 A: L$ S, @
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>6 k# S, w' A4 A1 R+ Y1 I/ r5 j3 u$ o
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
( ?' c4 J" q1 `( ]% z<P>{ </P>2 v1 \. c: D5 O$ O$ b; R9 q
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
: D4 j& y% K) F# R$ B! v+ ]. F<P>ListView1- &gt;Items- &gt;Item; </P>* L* Y6 {. \6 Z0 J" A
<P>ListView1- &gt;Items- &gt;Item= </P>
! |6 i9 S! T$ V& N! W; z) i+ a+ _<P>ListView1- &gt;Items- &gt;Item[j]; </P>% j& k* G) }; O
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
; p! M( _  h- u5 Q2 h<P>ListView1- &gt;Items- &gt;Item[m]; </P>8 _. R/ d8 s7 j
<P>} </P>
7 S5 J/ `& u6 c3 s2 d<P>} </P>
" l* A8 M; M. H# ^<P>ListView1- &gt;Items- &gt;Delete(m); </P>7 x4 `1 ~6 v+ P6 Y" }
<P>return; </P>" _& e* U0 d( a0 L7 `; Z: x# y
<P>} </P>! I: x0 e( y, n1 `! P2 v, G
<P>  </P>
: X0 l4 |3 d$ Z% R* d: D, L! I* N9 H6 H<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
- j9 W" H) c6 ~+ K# P( g! d* [<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
4 x' E9 z( O; f* M0 s# q6 S# c3 V, r<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>3 J: e" N/ A+ E9 M" ?
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
; C- P' n1 d  O* H<P>ListView1ColumnClick前面即可。 </P>
' L9 W! [; P0 F9 Z' V$ @( Y5 W) ], d<P>#include &lt; vcl/dstring.h &gt; </P>& n. |% f) L/ \  V' P% T. g  V
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>$ ^0 M0 X# a/ q- A3 q' ?5 {
<P>{ </P>: D% |; p. f) S1 i, N
<P>int l,i; </P>
, ]' S0 v' \3 d' \7 Y$ h; l. C<P>AnsiString qq(str); </P>
3 j6 R6 s# a( C4 h0 |<P>l=qq.Length(); </P>  W3 E7 N* d5 y0 ~$ I/ ^
<P>AnsiString p(str); </P>
! j$ G5 n- W  t4 t8 {& R! w<P>char a[]="\r\n"; </P>
$ X, g, v) o6 Q<P>int j=0,k=0; </P>
9 W/ H2 X' Q1 I# `) w/ ~1 W7 n<P>for(j=1;j&lt; l;j++) </P>
  N# B* d# U7 H/ u- x4 ~6 ^7 a<P>{ </P>
6 x+ J5 \: n" K7 u4 ~. j& ^<P>i=1; </P>; O. m. U3 C7 J3 }9 b# S8 z
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>( j- ]* [+ _: [1 P8 p! K: D
<P>{ </P>
$ G: c: |+ Z9 K1 f4 S<P>p[i++]=qq[j]; </P>2 k; S* B# {6 i
<P>j++; </P>
, j, m5 m$ }3 [<P>} </P>/ f* n4 Y% b2 }& U! n8 A! x& r
<P>k++; </P>- f0 s, w/ [- u0 Q6 u
<P>if((k-1)==n) </P>
7 [) p& M+ |1 o' R( B' H* g# }; r" l. p<P>break; </P>9 w- p. X( U- R! j* q: }5 x; R& N! x1 W
<P>} </P>
! ?9 I% L' H  U/ {% ~- u) Q( Y<P>p=NULL; </P>
  w6 b4 A. X8 j$ \, i! l<P>return (p); </P>
  G  x' h; @( x6 U$ M& @<P>} </P>' T! R( f! a5 A0 }
<P>  </P>7 k7 b) H  l) x7 {. O8 f/ s
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
1 G. N1 I0 p- I8 P<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>. t" w) s. S$ L( g$ j
<P>可完成对此项目的点击排序功能。 </P>; l% d' s, ]- E: W' D* {1 L
<P>for(i=0;i&lt; m-1;i++) </P>1 {% ]4 O7 N3 x3 s
<P>for(j=i+1;j&lt; m;j++) </P>
. N3 {0 O4 S% j2 _2 Z8 v. H1 r2 A<P>if(od) </P>
# J, v, r% @( ~3 H0 _<P>{ </P>
5 |6 X! `/ Y8 N* b" u5 C; f% O<P>if(sg(ListView1- &gt;Items- &gt; </P>; L; _" M. R/ Q2 A. |# {
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
+ q! W% l+ i' Y0 r, k& o9 ^<P>sg(ListView1- &gt;Items- &gt; </P>1 d) V5 l0 O( a7 c  p: \* U3 G/ u
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>7 O% z  J, z! P( |

2 F: ?# F; z+ b<P>// ...以下从略 </P>
5 Z( Q7 W# y4 D9 ?: ~2 ~<P>  </P>$ R) d2 m' L1 g
<P>最后,删除临时的交换项目。 </P>
2 ]. M! v+ Z7 \1 M: T<P>ListView1- &gt;Items- &gt;Delete(m); </P>& t7 q  U) L& h. s2 R' ~
<P>  </P>
* K( _" E: K2 r% F6 a<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>3 ]0 H/ n8 d, J. }, @
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
& I" Y8 x! g1 H; I% k1 I% m7 {<P>  </P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-6-12 19:01 , Processed in 0.407954 second(s), 52 queries .

回顶部