QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>, [" S. h* g+ R) K. r; o
<>  </P>& D% d  z3 y+ n! t) i
<>天津大学电子与信息工程学院 </P>" M5 m$ A! k2 o; V7 S
<>宋天宁 </P>4 J0 y" U! o' p% u  d9 J
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
. ~1 H" r8 ~! |4 _( D, @3 _. v<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
, y; `" c) d$ m. J+ A1 Y! K' M& g<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
$ C! V$ Y8 j2 X/ O7 y$ L( E6 }  S1 G<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>) ^/ J. e# E; N2 d7 o! `- Q
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
% y( w0 ~* R% m+ k<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
" j1 X7 Y3 c! ?) f# h<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
3 |6 K1 G- V0 f8 {$ R$ B' K<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>5 O! p( p4 {% F+ b2 b9 L( V
<>写自己的代码以完成这一功能。 </P>' X0 ?1 I% y& {1 V$ o3 R; J
<>  </P>
1 Y, I+ I6 r" ?9 n3 C<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
& _+ z2 F" ?" T7 ~2 b3 U1 p; ^<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>  s. y5 p& \8 X8 ?* p" K8 l
<>内容以升序排列。 </P>
9 e4 J/ a0 W+ y1 @9 O1 e<>  </P>7 e9 p7 K' B1 F. E3 \# A7 E& e/ O
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>3 b/ V# w* e3 K& p7 S
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
, ]9 W5 H$ \) D3 ]1 D<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
. q8 e; U- M: H( m! ]<>包含子列和主列上的内容)。 </P>
7 \& t/ p9 q% {6 o% N2 {( b<>  </P>
+ N' L( ^* _$ G<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
' S0 r" C( X. u5 v$ T) p7 R/ A( e<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
% ]$ {  p& q8 a# R<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>" B( z3 c2 y1 C1 h
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>" T7 ]* p- l4 v$ r. K# h4 b0 u
<>  </P>
6 O+ l2 e4 {# L, x' _: l<>  </P>
5 a" D8 Q$ ?2 h* |<>void __fastcall TForm1:istView1ColumnClick </P>
9 d. x( A! t0 `! b0 Z5 }<P>(TObject *Sender, </P>
: f$ _( l( c- L/ i& ?+ O' b8 Z( B<P>TListColumn *Column) </P>* _2 q4 A* d1 T' P; D/ y
<P>  </P>  n& I; S8 w' N' Q  r& e' k
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
! \# ~" k4 A+ ~  x1 U7 _' X' {<P>点击的列的信息。 </P>
% A$ c1 z8 ~; J8 x( w( Z/ W<P>---- 下面先定义变量: </P>3 \6 h0 L+ p' m  X3 }# D
<P>  </P>3 `7 O" ^- S0 }& j
<P>int i,m,n,j; </P>
, {" n. G0 X/ @1 D<P>static bool od=true; </P>; |$ \$ S, z1 h! t
<P>od=!od; </P>
& |  \* `8 e; D8 W<P>  </P>" T$ t2 x, l0 g& ^* n
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
" q2 `+ G+ Z+ H) g& Q<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>. m$ n7 S; }5 d; b; w
<P>列表框中的总项目数。 </P>
' p9 P6 f2 j. h3 p: b<P>n=Column- &gt;Index; </P>4 d5 N5 v# D9 O. b  y* s$ e
<P>m=ListView1- &gt;Items- &gt;Count; </P>
; T4 h: O; Z, |- T9 L% R<P>  </P>5 S, z6 Y) a( v# Q+ g' Y
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
8 y  p9 j' a% j+ G* w<P>ListView1- &gt;Items- &gt;Add(); </P>0 l" P9 ~) ?4 s: I# K
<P>  </P>2 \+ u! V: _/ M/ L) I" @
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
* Z' q' f/ U" j6 z$ }<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>5 V6 ?  ?; u6 p. _: r  K1 h" @) J
<P>if (n==0) </P>
: M5 a% o( l6 p) @( S3 S<P>{ </P>5 x" F& V( i* u3 Q  f
<P>for(i=0;i&lt; m-1;i++) </P>
- P; J. v) A# L  r; R' i<P>for(j=i+1;j&lt; m;j++) </P>
) F1 [- K  b: c1 f4 o<P>if(od) </P>
/ j7 t7 c* C( `/ b" J3 V; E3 e<P>{ </P>: @" m2 v/ s7 ?
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>! R1 F$ B" d% o* ^3 }$ z* h
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>0 C  _/ A5 S( w# J8 S) I) M
<P>{ </P>+ M1 {7 }6 d: ~8 Z
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
; e. y0 ~" g4 u8 S% c<P>ListView1- &gt;Items- &gt;Item; </P>  i7 G4 L+ E- Q9 U+ |" u  \) u
<P>ListView1- &gt;Items- &gt;Item= </P>
) T% J. U. o' c% l) @<P>ListView1- &gt;Items- &gt;Item[j]; </P>
+ l' J- L3 p1 k- B) b- U2 y, A, h) ^<P>ListView1- &gt;Items- &gt;Item[j]= </P>7 i4 Z/ S2 T7 z
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
8 b0 T) k' v. X$ q<P>} </P>
! F; a8 U; N* m" y' e  @<P>} </P>, p) z3 m6 c3 r  B
<P>else </P>
8 s9 m' D$ H- Z<P>{ </P>) S1 p9 ^4 h9 M* Z* u
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>6 C) B( N$ ^+ a
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
1 O" @+ C& C# Z# c# M<P>{ </P>3 y/ g4 e9 ?* [5 L
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
' g$ n( x* y7 o5 h, `, m1 w  Q( D<P>ListView1- &gt;Items- &gt;Item; </P>
+ e& H3 P+ e. C3 z1 [' Q) ?! G9 c<P>ListView1- &gt;Items- &gt;Item= </P>
1 K& X  I! z) |) V; J! l, g<P>ListView1- &gt;Items- &gt;Item[j]; </P>3 e3 q: @0 f. x5 n, B
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
9 s1 @- \, Y. E0 x8 S<P>ListView1- &gt;Items- &gt;Item[m]; </P>
# v+ u; V9 g: ^4 e7 F0 ^% g<P>} </P>/ I& q. ^' b6 L& [6 T* L6 |
<P>} </P>6 E5 L/ Q# E7 K
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
2 C4 T. I( B- v2 B2 P+ a- I$ d<P>return; </P>) i9 [4 T  Q' F+ l" F$ |3 N( S8 |
<P>} </P>! `, z3 |1 b! K! V' I+ Z8 k# f: z
<P>  </P>" Q3 T; n  x' X# n8 \
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
  v  I. \, I# x8 Y4 g" c<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
7 P5 p/ B* N$ Y<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
% s6 `  }9 [$ c8 i+ p<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
/ N" l1 S, b9 q7 t2 O. ]<P>ListView1ColumnClick前面即可。 </P>
4 r! B* \5 B0 g5 h<P>#include &lt; vcl/dstring.h &gt; </P>. w4 o4 E; [, e0 ?* b
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>- y9 d9 c# n5 V4 a
<P>{ </P>- d; o6 e# }# k1 n9 j
<P>int l,i; </P>
7 ^! i* P! d5 D; E* ^' z+ v, e<P>AnsiString qq(str); </P>
6 e3 [: G: a: i<P>l=qq.Length(); </P>; Z7 K8 d/ k) m+ u
<P>AnsiString p(str); </P>
* v8 z8 X1 J" _: [5 A% q<P>char a[]="\r\n"; </P>
4 b* S+ ~+ m2 v<P>int j=0,k=0; </P>
# ~5 B' \9 m( Z0 N+ O2 |# l<P>for(j=1;j&lt; l;j++) </P># |3 e6 L0 h; z9 g" e# _  s8 O
<P>{ </P>1 s+ T2 `5 D/ Q0 G/ r0 S
<P>i=1; </P>) {5 E& g. r% K+ l$ H
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
% }+ w  I$ h( W<P>{ </P>- t8 K, O5 A7 p9 J4 r* U3 g' K3 I
<P>p[i++]=qq[j]; </P>
/ e: ~* w% @3 q7 J8 \6 z% S<P>j++; </P>
6 [8 X9 _/ C* Y6 j<P>} </P>, m8 S/ j/ T6 q) w9 W/ B
<P>k++; </P>
) Z. U3 Z* ^$ ]& z, a+ R4 E. k' k+ n<P>if((k-1)==n) </P>
  ?' k* w% V' z<P>break; </P>
  p/ k# X; e4 H$ s<P>} </P>4 c- E3 Y  K0 A* r2 i
<P>p=NULL; </P>' b- `% b! i7 C* S
<P>return (p); </P>
' C% L. j) T2 l3 {% D# V  g<P>} </P>$ ?! ^9 }# Y6 Z2 f- U3 c6 N4 {7 V' y
<P>  </P>
. N9 `0 m3 o, Z: b" T, ^<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
, q* A+ z( T! A2 ^1 j1 Q  V* M<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
5 a2 a4 W+ Q+ x7 h9 ]* T<P>可完成对此项目的点击排序功能。 </P>
9 x- \$ t9 q6 _: M( m0 t/ S0 [<P>for(i=0;i&lt; m-1;i++) </P>
5 [0 S8 l4 w9 P  F& ^6 w7 w<P>for(j=i+1;j&lt; m;j++) </P>) o+ e& G. Y! V! M$ M: m- a
<P>if(od) </P>: n4 V, `3 T# v  i6 l9 k
<P>{ </P>$ z1 X6 L6 I& n  A0 x
<P>if(sg(ListView1- &gt;Items- &gt; </P>
6 [5 M+ _' v3 B& f% |<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
+ N. g/ C7 P- j1 d  N4 K+ l<P>sg(ListView1- &gt;Items- &gt; </P>
, F/ n) H4 J+ M" g<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
, B( Z( ~* t2 }  z
) V4 }. I) E3 S/ z( {3 _+ m7 \<P>// ...以下从略 </P>) }2 {! h% n0 T5 ^+ T( K9 a3 k
<P>  </P>, ~4 u/ j  @  w- [- r, O6 W
<P>最后,删除临时的交换项目。 </P>7 @, W9 |9 N; u& j' v# A4 p
<P>ListView1- &gt;Items- &gt;Delete(m); </P>% {' n: Z6 E/ p( D* p2 t7 j& @
<P>  </P>
+ E- E  A4 K$ e( H8 ]<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
" R% I$ [  X) s6 D4 g<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
8 G; S( _+ M% V* J<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-8-9 02:43 , Processed in 0.748740 second(s), 52 queries .

回顶部