QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
2 M' c/ N  n/ l, d<>  </P>1 }9 V0 |! l6 H  d& G
<>天津大学电子与信息工程学院 </P>
! n& D4 _% x/ L# a+ L7 e<>宋天宁 </P>
: b* ~/ ]; Z4 H& _. f5 @# k! j5 e<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
8 _' k1 i$ G; U0 F2 R( Y$ Y: b<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>4 _! `% k9 `0 Q2 a/ w7 s! X
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>  J+ Q4 L, \# Q& N
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
. a( ^4 b$ u/ h2 a! G5 ~3 F<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>( u0 Q( Y$ M- q
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>) O: Z; ?3 \9 r. ~' W6 x/ J
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>4 j; W, M( }  g
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
, q7 o. m; o) c: }: U2 W<>写自己的代码以完成这一功能。 </P>5 H* W+ p5 C. U+ L* [8 M5 z! g
<>  </P>% k7 _6 P7 L" {, b' S
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
+ N2 o2 `4 J' m! f<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
. {8 t! E# R6 N9 D, M2 z<>内容以升序排列。 </P>& }9 m$ \8 v( C3 R# G' `
<>  </P>  B) ~" `( W9 W& Q
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
4 M$ \& Q9 \3 A7 k<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>8 S6 M1 ^+ v4 }! ~: p9 E
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>1 F; H% ]9 j) C1 L( [
<>包含子列和主列上的内容)。 </P>
7 f, s2 @  ?2 U& w& [<>  </P>
- F( Z( m; S$ Y/ W1 v. N7 A<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>. M" B0 d# g6 _
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>8 ?. e/ j+ k0 h' f6 E+ [
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>' g) p* c8 B& \3 h7 w, g0 h+ \
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
3 ^/ b1 u, E4 H% l; y6 [8 J<>  </P>  J5 y0 g1 o1 C  n2 ]6 j2 |+ q  d
<>  </P>8 g' A/ p9 d1 R0 l8 @- d6 }
<>void __fastcall TForm1:istView1ColumnClick </P>
+ e. L* J) X0 B9 E/ J5 \<P>(TObject *Sender, </P>
+ e6 g3 Q- N; b( Q9 Q<P>TListColumn *Column) </P>
" b  E& R9 S% F9 {<P>  </P>
+ x- _9 N3 G8 t) u  F<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>+ R% O& W. A3 W
<P>点击的列的信息。 </P>
7 ]: E+ ]2 I2 ~; u: d<P>---- 下面先定义变量: </P>
; v9 [  q- z, p% g" I3 F3 p( N* ~9 S<P>  </P>
. N0 o3 \) @# f3 g  x) L! T9 `3 V<P>int i,m,n,j; </P>  ?8 `) M1 H6 U, a1 m' O
<P>static bool od=true; </P>. U4 V: F+ E- Q+ k! q" m; u
<P>od=!od; </P>8 h; z4 ?, I" [) W- e
<P>  </P>- X$ A1 _- c3 U
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
# W9 Q# O2 Q& K$ {$ z: o& ^/ C<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>4 V2 `! Y4 m5 x  f5 q8 y+ o
<P>列表框中的总项目数。 </P>
2 Y' ]1 r. D( E6 _5 D5 y/ d<P>n=Column- &gt;Index; </P>4 \9 \: d1 q/ Q
<P>m=ListView1- &gt;Items- &gt;Count; </P>
& ^4 V: U/ k/ W- }# w1 I<P>  </P>
5 Q- p, w1 D, s' J<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P># n0 `  x5 [: y' z& H  ]
<P>ListView1- &gt;Items- &gt;Add(); </P>
  F3 y3 p$ s/ Z<P>  </P>* K; A1 g; e* U: r: P' _
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>$ n' v' K3 o% g% F) `, f  L/ x4 Q
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
  F) Q- z9 Y' o% X& ]+ v<P>if (n==0) </P>
5 L/ B: ^% T6 H5 u<P>{ </P>: d1 h# H7 m! U- S0 ~3 V1 f& u
<P>for(i=0;i&lt; m-1;i++) </P>% b3 U3 }8 B/ E- k! }: y) }
<P>for(j=i+1;j&lt; m;j++) </P>
8 J) }' m9 @9 p$ [. a. `<P>if(od) </P>5 G- P$ m1 K6 K7 L- d
<P>{ </P>
0 F3 H" R1 M% ?$ _3 h# w% W<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
3 _2 n1 T. x; f8 u6 X0 F- R+ b<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>5 k* w3 e2 D' Q  O0 \# p
<P>{ </P>
; N% O. @) _& Y0 ?* q4 D<P>ListView1- &gt;Items- &gt;Item[m]= </P>
, L; X. P6 h/ ?4 `; e3 k<P>ListView1- &gt;Items- &gt;Item; </P>
8 i5 I4 |9 m/ n  c. V) X7 u<P>ListView1- &gt;Items- &gt;Item= </P>
& }% x1 d) C- p# `- M% I<P>ListView1- &gt;Items- &gt;Item[j]; </P>
0 N* z$ k, \" s<P>ListView1- &gt;Items- &gt;Item[j]= </P>$ S6 X# r5 i/ e4 L$ h; M
<P>ListView1- &gt;Items- &gt;Item[m]; </P>' ~" t, E* U& m; Y) k% P9 j
<P>} </P>
1 E- C* B4 {+ U8 i/ L! z<P>} </P>
9 E- O4 l- ?& m4 \<P>else </P>- n2 H* D) W# `( M( F6 D
<P>{ </P>
% [* x% A, W& b% [+ v8 t2 t<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
7 A" E6 t9 w: l<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>7 [+ M% M2 X* S& \4 C1 m8 v9 c7 N
<P>{ </P>
$ I9 ]8 s! J, Y2 ?. Z, Q; D- l<P>ListView1- &gt;Items- &gt;Item[m]= </P>4 i! L8 d! Y- D
<P>ListView1- &gt;Items- &gt;Item; </P># ]6 }6 |- e  f8 q
<P>ListView1- &gt;Items- &gt;Item= </P>. \1 y9 H/ o/ S
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
3 Y; J. Z$ f: P% l- b4 G2 @- p1 Q' T<P>ListView1- &gt;Items- &gt;Item[j]= </P>- N8 t0 M) D. l
<P>ListView1- &gt;Items- &gt;Item[m]; </P>' O: S( M# y5 y" b
<P>} </P>
) G4 k/ J5 @+ t# a<P>} </P>) c) v9 l4 a( C
<P>ListView1- &gt;Items- &gt;Delete(m); </P>9 F& ]2 b! R: F) W( p4 ]
<P>return; </P>( m4 l0 k6 j5 ?+ S- m8 Q
<P>} </P>
! D2 r- v+ G- Y) F/ Q5 {7 N; ?<P>  </P>' F7 p2 H/ P+ s! i: z6 }
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
$ |0 P* l" T( v( l<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
2 G9 g& P, q4 |- r* z8 ^! p<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>4 `# m+ `* X5 h
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
+ m( }: I8 f( I- h+ m& F<P>ListView1ColumnClick前面即可。 </P>
5 T- U$ w2 ^& j1 J- x5 n<P>#include &lt; vcl/dstring.h &gt; </P>
9 B+ J" A2 v) [) p5 G( e$ \! s8 N& I<P>AnsiString __stdcall sg(AnsiString str,int n) </P>4 Y2 q) I$ p! g, X
<P>{ </P>
6 J+ U& L8 [$ A) C/ ]<P>int l,i; </P>/ n  N. l; I% [% k
<P>AnsiString qq(str); </P>$ a- q! B( O: U8 E: j3 x
<P>l=qq.Length(); </P>  a* b- m( k4 v/ O- r
<P>AnsiString p(str); </P>
+ i7 w8 B* m, J$ e1 c. ^" w+ v<P>char a[]="\r\n"; </P>5 h0 ~, Y  F5 v
<P>int j=0,k=0; </P>) n$ O( b5 O" |0 F7 S, J
<P>for(j=1;j&lt; l;j++) </P>
8 z2 a7 m$ Q; n4 T; {% S<P>{ </P>" W2 `# V# ?5 h# v
<P>i=1; </P>/ I. s& m0 \0 o+ Q, B! l
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
, w% L( L' X4 f' g0 Q+ c% a<P>{ </P>
4 G! L: F4 P' A! A; a5 Q7 p<P>p[i++]=qq[j]; </P>3 W+ r! Z7 }4 o
<P>j++; </P>
0 V" ~7 _# P$ t6 \, [9 r' ^4 E+ c<P>} </P>) T* H: K9 b+ k( W! ]* W* a- t
<P>k++; </P>' |2 q( w1 ~0 D3 N2 s0 U
<P>if((k-1)==n) </P>, D2 C# Q$ ?% \) z4 |- c
<P>break; </P>
* ]* I7 O2 o8 g( j% P2 g<P>} </P>
% S% G3 M5 }4 j8 D; l7 A8 Z<P>p=NULL; </P>
3 L2 W: v! V/ [5 w; M<P>return (p); </P>3 w# f2 U+ e, c9 ?
<P>} </P>8 ?  c0 K' ^% R. Y+ V6 P& T
<P>  </P>
6 N& p/ L  L" g8 [% W& o" Q<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>0 x, F* [8 x) I" C& D/ C
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
% J/ T  |7 Q% @0 _% f/ F# T* p<P>可完成对此项目的点击排序功能。 </P>
! y: a1 i5 i" m5 L# H" R<P>for(i=0;i&lt; m-1;i++) </P>
  l9 s/ Z+ r4 a7 r8 u1 Z" G<P>for(j=i+1;j&lt; m;j++) </P>
3 G1 D1 T- O% N5 X  b0 n<P>if(od) </P>
" ]( c, B$ s5 _; H) V2 L" q2 E9 u<P>{ </P>
2 g5 y4 }- C6 o) ^' q<P>if(sg(ListView1- &gt;Items- &gt; </P>
- G. \) ^/ B+ N7 A# q<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>; V" }, j2 Z  O" X% d
<P>sg(ListView1- &gt;Items- &gt; </P>( X# {8 |% S& p8 W% N6 x
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>6 k9 |) N5 P9 ^, a6 Z% W6 a$ [

: L' i3 i! C9 b* e<P>// ...以下从略 </P>
+ m5 v) {$ _( f; s: t: m4 C<P>  </P>" C( T1 i: B  A1 L$ W
<P>最后,删除临时的交换项目。 </P>+ ~0 ]$ |5 T3 L+ O/ G
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
; P! b0 a& \1 K3 M<P>  </P>
; t0 a/ C7 T* A) g<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
0 i! T; ^6 j  C+ f9 c& }<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>: O" l9 p( ~# {5 i
<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-10 20:08 , Processed in 0.404122 second(s), 52 queries .

回顶部