QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<>  </P>
3 O3 c, L0 L/ h: R+ O5 l<>  </P>
7 x* q( O3 h# l3 {" ~+ d<>天津大学电子与信息工程学院 </P>
& @0 W6 Y* ]7 Y9 m# s8 M<>宋天宁 </P>
( A& a7 H, \# [<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
6 B4 R9 E- o0 ~+ t<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>* L! v1 D/ E: a) `
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>* S3 Q/ N5 j9 l9 ^. T
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
; ]# U) i! k& J) Y3 o6 R$ X<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>% b) v" [% s- ~* \
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
3 r. K) x- D1 K% i  Z: }+ M* O/ D<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
2 k: m% R2 H7 L* U! }<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
' x+ `6 Y! q1 `9 o% f<>写自己的代码以完成这一功能。 </P>* V& a& n) U( v5 s, c! n
<>  </P>
/ t3 ?, I5 A) ^<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>5 C. _! R. V, C% M* m) u
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
( G  s' Z. f& s: ^<>内容以升序排列。 </P>
7 z  m% e8 f1 T5 Q<>  </P>+ b- ~$ @) f/ H8 b) v
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
+ P3 I2 t7 u9 z$ s' y  u  V<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
% H$ m. J" U% `<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
6 h3 `: X9 l/ Y<>包含子列和主列上的内容)。 </P>
; I+ v+ g7 O8 x  g" S<>  </P>
$ e2 x( L$ E* l1 f2 o<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>0 ]$ h( f$ Q! N+ U8 ]$ v5 A
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>6 O- N/ \# ]- n9 Q1 v* ?
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
/ ?9 }% @! q+ x% Q& c* u<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>. q9 Y: Z$ P8 E5 L" Y" @: |
<>  </P>) m2 k4 Q% M7 V/ C% t: o" X
<>  </P># ]" O+ e; Y$ ?0 B
<>void __fastcall TForm1:istView1ColumnClick </P>
3 {8 b& e& ]# ?& V5 l/ ?<P>(TObject *Sender, </P>% u2 x, R* U2 O1 G; \" O
<P>TListColumn *Column) </P>6 |( K( x" Z, t2 O1 S2 x/ x
<P>  </P>
# a4 T. r6 A) B<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
/ c6 g" X7 e% }' A. ~<P>点击的列的信息。 </P>. T' `; z$ ~( T8 h4 X3 |; N
<P>---- 下面先定义变量: </P>
: r4 B5 O# B1 d9 P- N) i  O<P>  </P>/ x& S) G  T6 [6 W9 S: f
<P>int i,m,n,j; </P>
8 |  Q9 }( A/ ^% |, u2 k5 V<P>static bool od=true; </P>1 ]9 H, c" T7 U7 I. R- S
<P>od=!od; </P>
0 p* x' |7 t8 X5 v. U6 P. p<P>  </P>
: _* u; T( }0 |7 t3 P<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
2 _) p' O* \2 z<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
; C% A. Z' m8 r1 d. E& T: C<P>列表框中的总项目数。 </P>* x4 Z3 r, T# Z2 M5 N
<P>n=Column- &gt;Index; </P>7 Y1 a, ]( i, n$ {6 n) R$ G
<P>m=ListView1- &gt;Items- &gt;Count; </P>
5 G4 R# V2 F( Z5 q. ?  @<P>  </P>
' |1 r  \! y  e<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
4 K/ l+ X; G% q  g<P>ListView1- &gt;Items- &gt;Add(); </P>5 m$ V0 G; j2 P  }# ]& ~
<P>  </P>
, c+ J7 b2 w+ B' ?, J" h6 y<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>4 \/ S9 ]' r* v( C7 V* Z6 X
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
- r" _" E4 u( c  R" s+ A<P>if (n==0) </P>3 K, Z5 k& q* ?" }
<P>{ </P>. G; Q4 h! o3 u1 F- ?2 `8 J6 V
<P>for(i=0;i&lt; m-1;i++) </P>
  ?3 r1 b' @  g& h. w$ U4 t0 G2 V0 k<P>for(j=i+1;j&lt; m;j++) </P>
* x, _3 W) q) q- g* M3 e" m7 e' ?& Y<P>if(od) </P>! Q% r6 W2 k+ e6 T- [2 \; O
<P>{ </P>
$ O6 W; Q% h9 Z4 Y: N% o<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
0 i6 g/ i* t8 l<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
4 U  r! T! I" k) r<P>{ </P>
( [' _/ W/ t1 {" e9 X2 ?0 q<P>ListView1- &gt;Items- &gt;Item[m]= </P>
* t4 b, X' e0 p( G; S9 F+ j<P>ListView1- &gt;Items- &gt;Item; </P>$ R- p$ L+ B4 H
<P>ListView1- &gt;Items- &gt;Item= </P>
: \7 w; g& G1 G; F' S; F3 H<P>ListView1- &gt;Items- &gt;Item[j]; </P>
; S& R/ R! ?. ~<P>ListView1- &gt;Items- &gt;Item[j]= </P>
7 G% F0 }  {" N8 x: [. F<P>ListView1- &gt;Items- &gt;Item[m]; </P>' e8 F; d# A. i, e( U% q+ d, P
<P>} </P>* T2 [1 H6 m3 h% L$ `: I, v: D
<P>} </P>& V' _) d' I: i( a; V) u
<P>else </P>9 n6 m1 z% e0 X, \+ L' @/ z& P
<P>{ </P>* G! k9 j- x2 r1 J1 }
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>- {) r2 ?+ L0 h3 s, Z9 }' @
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
( u5 A" a3 u  N9 g9 {" ?<P>{ </P>
# L8 K, b9 E6 ^<P>ListView1- &gt;Items- &gt;Item[m]= </P>
* V3 v1 E" T5 _  ^<P>ListView1- &gt;Items- &gt;Item; </P>5 n" {4 a4 O7 f3 ~2 X
<P>ListView1- &gt;Items- &gt;Item= </P>- Y+ g3 j: _( f/ t4 o1 {
<P>ListView1- &gt;Items- &gt;Item[j]; </P>4 r6 m; D; U; _0 [' k
<P>ListView1- &gt;Items- &gt;Item[j]= </P>& K- h! J6 V3 b) B9 b5 f/ M! O: \
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
7 G/ i7 J' T; f) c0 l8 ?$ e  p<P>} </P>7 o: i/ H: `* |- M# V. f
<P>} </P>
5 `; [' T0 d- M* B' F7 f( }9 E# _: U0 Y1 b<P>ListView1- &gt;Items- &gt;Delete(m); </P>
0 R/ ]" b3 H% x<P>return; </P>
; @7 j/ T. \0 r: a<P>} </P>, T, U2 ^% l" x# f) z3 `
<P>  </P>
" {1 M* T- p2 t<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>% e* X( z7 s% Z
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
# A8 @& H/ d3 d7 R% |/ w7 X- `6 I<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
5 i2 m/ ^  \/ \, c# T<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>7 \( v8 p: E/ c
<P>ListView1ColumnClick前面即可。 </P>1 O$ U8 V+ O) C6 A. Y/ e
<P>#include &lt; vcl/dstring.h &gt; </P>
5 i3 y$ x( M7 u<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
) g3 k' E$ H1 v<P>{ </P>" l, m' V+ }5 ~
<P>int l,i; </P>  y% N% u! d" |2 E7 j) R( p% h
<P>AnsiString qq(str); </P>1 g' t/ q% _7 \. v2 V! i
<P>l=qq.Length(); </P>6 q+ M# C7 k7 x8 ~
<P>AnsiString p(str); </P>
2 Z; A" ~# m1 O% \- r7 G- a2 A( W<P>char a[]="\r\n"; </P>5 \! Q9 p9 i; k9 a; {
<P>int j=0,k=0; </P>
8 T! a* P+ B2 r8 Y. w5 h! g<P>for(j=1;j&lt; l;j++) </P>
; G$ G! R$ N" \! R  H( C- W6 K<P>{ </P>
6 h6 n6 N- o: F6 t<P>i=1; </P>
' y4 o, h! I: F' p' [, M) P<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>9 a' f- P3 \' d$ a( d$ Z* }
<P>{ </P>, n0 [( l( ?7 R, Z
<P>p[i++]=qq[j]; </P>
" N4 v7 o6 C  G<P>j++; </P>; ]6 P5 ^( }- `& X) F
<P>} </P>
9 v0 T/ P8 `& N8 P; `<P>k++; </P>7 P4 }& T2 F9 U$ ~8 R5 b, n7 h
<P>if((k-1)==n) </P>% t6 o; n- z7 S) ^0 Q! Q$ Z
<P>break; </P>
; h5 E$ }# [- g* t* G0 _. j7 ^' c* L! ^* Y<P>} </P>4 x: m+ R0 N" ^5 x0 n% E( u
<P>p=NULL; </P>, j1 u* G8 u2 w, g8 T- X
<P>return (p); </P>
3 U. E7 v! f/ r& {8 {' \<P>} </P>
. @0 s0 x: i: H<P>  </P>3 q; w, e4 r  J% R  E$ b" n5 Z
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>- |, b6 r5 E5 x: }1 P/ k  j
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>4 x/ j! O1 u, s( ?3 c+ ]- I8 X
<P>可完成对此项目的点击排序功能。 </P>& s4 x  _* F9 T* h' k
<P>for(i=0;i&lt; m-1;i++) </P>9 n* B5 o9 ?& l" G. J# [
<P>for(j=i+1;j&lt; m;j++) </P>
- P' M' H" i9 d) ~<P>if(od) </P>1 A( |6 q9 K; T2 P8 i! C+ f
<P>{ </P>
6 d3 T, D) j  D' C4 b9 Q' y<P>if(sg(ListView1- &gt;Items- &gt; </P>$ B8 }& _! d  q. Q: O
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
( Q* ^- @. C  I2 I, @: i+ G) ~<P>sg(ListView1- &gt;Items- &gt; </P>
8 V2 z& ^$ N1 w2 `<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>! D0 f# M: Q$ }% u0 W/ H

) Q% }: K" v  H, K3 F<P>// ...以下从略 </P>, V3 `& F/ ?$ E4 K
<P>  </P>: i: T6 i$ ]1 ~3 i9 m  z4 h
<P>最后,删除临时的交换项目。 </P>
9 P4 @; V# J1 R1 W) `% @<P>ListView1- &gt;Items- &gt;Delete(m); </P>( V; S8 ]& K/ N3 a! U( H1 f
<P>  </P>
5 O! }1 r! D$ `( k' K<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>: y1 x9 [2 B9 i+ k9 g  N- O2 v
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>1 H+ R) O: A8 g- r: o# X2 Y4 k
<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-4-20 10:11 , Processed in 2.454784 second(s), 52 queries .

回顶部