QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<>  </P>2 t& e# a8 @& `. C
<>  </P>
, J" [8 e6 Q/ z- C4 b, f! b6 e<>天津大学电子与信息工程学院 </P>
' _- x' v5 ], V7 l3 x<>宋天宁 </P>
/ I4 n% g9 G' T9 k<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
$ D! O/ W/ M5 e<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>8 k  K  ?/ K' ^# ]; d1 p" K7 _4 t: t
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>8 ~+ L. K) k. v$ H+ }
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
5 T$ @; i; L$ B! o* p3 u<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
  U# [- C6 f0 R1 U6 G<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
8 q$ F, k7 p( E$ p" S<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>; ]0 r. N# L& H4 M, c, [0 A
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>: q+ K6 k6 A! x; h" X2 n8 X. X7 D
<>写自己的代码以完成这一功能。 </P>) }6 |) N8 L6 @8 j3 e" Q
<>  </P>
! {/ F+ H- L, a8 U. u% q. V8 e<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
; ]) t4 X+ }! G<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>$ R& `6 q9 `; T' ~, W% h* [
<>内容以升序排列。 </P>
) U0 F5 \. ^& v<>  </P>- a+ E8 A  D* r% K8 X2 P/ K( r
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
. m& h; G5 r) h- A% }' X7 ]<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
- T5 u. g1 u) X- G$ K8 D; L/ }<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>! |; Z) e5 u+ \, V
<>包含子列和主列上的内容)。 </P>" i3 i3 Y* e/ D. M9 ]: B
<>  </P>
1 o( E. R; K. Z3 o$ s7 I<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>* h- \) b  r6 a
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>6 n0 V3 L( \) s& v
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>- [( c5 q% l- b! p; ~! @- F* O
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>7 E. G* F4 X3 x! y- k5 R
<>  </P>
9 W" G0 T$ G: E1 X1 ?0 X<>  </P>
& ^0 ]+ J9 d1 @* y( B6 ]/ G2 L) r& m( {<>void __fastcall TForm1:istView1ColumnClick </P>
. O! a' \. B$ `8 I% M4 k<P>(TObject *Sender, </P>3 ~3 K+ Y% ?/ c; t" C' d% M
<P>TListColumn *Column) </P>: n& g$ _7 r; ]5 s! r
<P>  </P># ?! h. w( |+ l7 D7 @# C% y
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
% G3 C# s" @' D& F% F9 o7 b<P>点击的列的信息。 </P>
$ j6 j  m1 P" o2 f<P>---- 下面先定义变量: </P>
" W& \/ s2 m/ i# |/ B% t6 a& S<P>  </P>
, e: i3 ^" g$ \2 J& Y<P>int i,m,n,j; </P>7 x% J% x6 ?3 {- [/ k& I6 Q' V7 l; R
<P>static bool od=true; </P>
) i5 M; H& P: [) g- s; t' }<P>od=!od; </P>! I& ?3 o  v, b; K9 e6 k* _
<P>  </P>
! W! {. s3 R0 |<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
$ l7 m# S2 c. T; s' o9 }<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>0 @6 |0 ~6 B5 s
<P>列表框中的总项目数。 </P>
8 Z* w7 |7 m7 r9 w/ z( {2 I. W<P>n=Column- &gt;Index; </P>- ?5 h( p$ G. l0 y: P) h# ]& W4 s
<P>m=ListView1- &gt;Items- &gt;Count; </P>8 _( \1 r" w1 W* e
<P>  </P>
6 E' f$ k8 _) A$ w<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>$ _7 m3 ?! U& X  D
<P>ListView1- &gt;Items- &gt;Add(); </P>. U" e9 o+ G- T/ `( X5 D( _
<P>  </P>/ X8 U; r! g* u1 k* c
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>. @, _6 x# f$ V7 y+ T! [! {
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>" ?$ Y3 ^5 j) D4 `) j
<P>if (n==0) </P>
! A! h; B/ _6 Z8 K6 `$ V& G% C<P>{ </P>7 m* H3 _, r/ E/ A
<P>for(i=0;i&lt; m-1;i++) </P>6 d" x6 r! i! F; K# k6 ^% p' Q
<P>for(j=i+1;j&lt; m;j++) </P>, n" h" G, k5 d* n2 X
<P>if(od) </P>
& c, \9 s- N% f* o<P>{ </P>0 g, l4 a1 z% U3 e, V/ T4 b* b
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>% _9 ^! J+ K6 G* s
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
" y9 v% A; o) T<P>{ </P>
& x+ n  f0 c) S( z8 M+ o6 t<P>ListView1- &gt;Items- &gt;Item[m]= </P>
0 i2 `$ v# U) ^  Q<P>ListView1- &gt;Items- &gt;Item; </P>; R) X. K( w# H8 o+ ?
<P>ListView1- &gt;Items- &gt;Item= </P>
! V; d* k3 _7 u* _/ O<P>ListView1- &gt;Items- &gt;Item[j]; </P>6 ?5 `3 u' q% v! G9 {
<P>ListView1- &gt;Items- &gt;Item[j]= </P>. L. G0 K4 p; C4 F: V" Q
<P>ListView1- &gt;Items- &gt;Item[m]; </P>! }1 F6 m, ~, N# A- w9 T" j
<P>} </P>* _7 L: O, s0 _4 x9 S0 m
<P>} </P>
7 D* e' \2 B/ B<P>else </P>( _& ?  m/ R6 P- {
<P>{ </P>
+ O+ t4 ~; T( W2 s6 b; p<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>+ r' N8 w$ d5 _8 v6 z1 `8 V
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
# l) Y9 I+ _% u3 ]3 {1 Q- t<P>{ </P># t& }- g& V0 y3 ^- Q9 R! c
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
2 ~5 l6 W& z  d2 k<P>ListView1- &gt;Items- &gt;Item; </P>4 o$ e0 J$ Y- Z
<P>ListView1- &gt;Items- &gt;Item= </P>5 D7 a# M4 a- }  ^+ ^2 n
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
- p7 f& k4 [5 S) ?3 f<P>ListView1- &gt;Items- &gt;Item[j]= </P>
  L% }  D) D* z<P>ListView1- &gt;Items- &gt;Item[m]; </P>+ }& w# P4 ]( k+ B: |
<P>} </P>; R0 A  M9 ^* e- ^
<P>} </P>0 C( p- x9 f& |$ E* @6 |
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
: u; _4 ^3 Y' p9 Z6 O- q6 {6 C3 n<P>return; </P>
2 W) Y' \! @9 @- r7 V  G2 `<P>} </P>
4 @7 t' ?: n6 c<P>  </P>
, B3 C3 ?* N1 b8 d; e) k<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
9 d( ~9 l0 I. x1 e5 n$ d" |<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
! k0 ?1 k4 }1 i- C: z; T<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
' c! s9 E) O6 }" r<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>! D7 J" Z- N; m7 S, F& {
<P>ListView1ColumnClick前面即可。 </P>: J6 N. l  a  @; _, {1 [8 i
<P>#include &lt; vcl/dstring.h &gt; </P>
7 e0 h5 E5 f; F4 c  i<P>AnsiString __stdcall sg(AnsiString str,int n) </P>0 D* D- y, [; `6 A8 ~4 x3 A
<P>{ </P>
' P6 u. T/ |4 {! W$ F1 ?/ Y# j4 ~. S<P>int l,i; </P>
) U" W4 x/ M8 }, G" j  t/ P' w<P>AnsiString qq(str); </P>
& l' _& |" R3 H# G<P>l=qq.Length(); </P>% h8 _% `1 M1 P7 G8 V* O  e
<P>AnsiString p(str); </P>
1 F: d" c( r  L  c5 G<P>char a[]="\r\n"; </P>
% r. z/ P; }; ~) a  f5 i6 k4 L9 {<P>int j=0,k=0; </P>. J* L" r" f) v9 w6 ~  q7 }
<P>for(j=1;j&lt; l;j++) </P>6 T4 q7 `4 C& e2 V: l( N9 p
<P>{ </P>
' h4 x8 P' E. r( t% w- J$ v" C<P>i=1; </P>7 g9 g/ M; z1 g+ b2 ?
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
7 s% [- \) k( V" {. `: B+ z<P>{ </P>& `* I5 w# v. G$ j9 r
<P>p[i++]=qq[j]; </P>
& D8 J; N9 j4 W+ I( s; ~1 A<P>j++; </P>
$ |/ c( S5 r# d2 M! Q# g7 R( J<P>} </P>
/ j4 c* I: |* N3 Z6 T2 p<P>k++; </P>' T& t. G3 }: n3 O! g# Y9 l6 Y
<P>if((k-1)==n) </P>
* f0 R/ _6 J9 S<P>break; </P>' Y' j( H8 ^1 \2 I% i
<P>} </P>3 ^8 _. U, Y7 h" ]
<P>p=NULL; </P>
1 t( {) ?+ s; u% e; c<P>return (p); </P>* B9 v9 z2 v# G! |
<P>} </P>
3 d# u  v! F. e% ~! F5 x<P>  </P>; h8 A' C* q8 U' g* [7 h: {
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>& n( s2 b. Q. M) \2 u
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>+ P2 Z( Z" F' I- C% n4 z
<P>可完成对此项目的点击排序功能。 </P>
7 T+ V# O8 F* l  g" C% q2 j<P>for(i=0;i&lt; m-1;i++) </P>8 ]4 d2 }1 E# F+ c5 Q( Y
<P>for(j=i+1;j&lt; m;j++) </P>
  d1 N# _$ d( b% W) h* F, c<P>if(od) </P>: V3 }% V5 D; g1 D* u4 I2 T. }
<P>{ </P>6 E9 |$ D6 n+ g; Q
<P>if(sg(ListView1- &gt;Items- &gt; </P>9 i/ Z- P7 ~3 R& `% u, y
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>3 A! a( [* p3 y
<P>sg(ListView1- &gt;Items- &gt; </P>1 Y7 e, ]1 S+ [, F, N( j% x
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
3 t. w  @; U* y) T. s9 o$ k
3 P6 J' a% b  a/ U; |9 w& h, M<P>// ...以下从略 </P>
' d! R, C% S9 A- ~1 R7 H<P>  </P>) I. J; c9 @2 S. f( R# m# H& S+ L
<P>最后,删除临时的交换项目。 </P>
' t" C' }! k  {5 U' J; H<P>ListView1- &gt;Items- &gt;Delete(m); </P>6 O$ i- s9 F6 b# V& @
<P>  </P>
, E7 X" ^+ d! x2 i3 c<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
1 N. p! x/ ?- o  r<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>/ W" \/ Q; R1 j' g
<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-11 08:58 , Processed in 0.421565 second(s), 52 queries .

回顶部