QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
$ W* i0 p3 q6 V<>  </P>5 J4 G7 s6 y! U! E
<>天津大学电子与信息工程学院 </P>$ H0 R7 ]9 \, @: ^
<>宋天宁 </P>" l' R$ W) ], I: y
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
" s2 ]" P. K5 N2 r. Y, Z<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>* t+ H5 x4 D, ]2 R9 T! J1 q  J
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
! p) X0 t' d  Y4 J( z' y<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
5 ?  j4 Q' P( K1 I<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>( e/ e3 N9 R. j+ f9 l, X2 a
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
2 F- b  N) U( c0 l<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
2 @! c* h5 ^- h2 r; R3 h& j' C+ X<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>8 S- e' a' x( b) r4 s2 q  t# y
<>写自己的代码以完成这一功能。 </P>
' W/ k+ p. i3 Q1 P. l4 D  z! X<>  </P>: P; |) R0 h' N
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
: {. F/ B* f7 I9 A  y* V. F<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>0 }- z" r* m7 M, c9 d+ w0 V! m
<>内容以升序排列。 </P>
( y( }" ?8 X( E+ [  `/ E2 R, X+ u<>  </P>
! \2 |5 ~$ v0 N0 z* y' L<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>7 C4 y; G  I/ V9 A! b
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>0 f1 k) S) N* s! `5 H  b# b
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>4 p! `7 v' d# V$ A  r$ i- v
<>包含子列和主列上的内容)。 </P>/ d/ ^. t( f- g) y7 g. s
<>  </P>4 b/ w. l+ n. q& C$ @  o0 w$ E
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>" O- g5 [# B+ i$ r# `  M2 J
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>& o8 X2 G& [3 c& n* U
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
8 f% D4 [% e$ f5 ?, Y: r) P<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
; a1 k7 z! k: `1 c$ E# U. f% l; j<>  </P>
' D: n; o" I9 v) R6 ]<>  </P>
* X; x$ U5 y* R6 D<>void __fastcall TForm1:istView1ColumnClick </P>8 _3 A; w1 y" R4 z
<P>(TObject *Sender, </P>) {+ i* w: _7 x$ v  J' T% q
<P>TListColumn *Column) </P>" l- g6 O% B- @1 M/ E+ `
<P>  </P>, c' \9 N4 B( k  G% O
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
  w) b3 O  l2 s' x9 P<P>点击的列的信息。 </P>
- G6 c$ h2 J! W4 d3 n6 N/ a<P>---- 下面先定义变量: </P>
$ p$ a) k0 C2 N3 R<P>  </P>' W2 {$ |& x1 w( E( _1 g
<P>int i,m,n,j; </P>
* b0 x0 D- v- K/ A# Y9 e+ X: a<P>static bool od=true; </P>
! Q/ X9 J6 \9 b6 L8 w) ^) u<P>od=!od; </P>: X0 U. m& L5 F, g& ]5 L
<P>  </P>- R3 S- ?1 o* \% }
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>/ L( [; o' c; {5 Q# E
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
1 N$ D- q7 A: f, J* i$ H- L<P>列表框中的总项目数。 </P>8 @+ o+ t2 |/ p0 D# `+ i. X8 {. t" g1 n
<P>n=Column- &gt;Index; </P>
) M7 T9 W, S% C) I$ ?6 S8 f- D' k<P>m=ListView1- &gt;Items- &gt;Count; </P>( p8 T; z$ [3 L
<P>  </P>4 p/ |! x8 n4 @; c) G7 H* ~
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
5 o6 }, S$ j3 f1 ~$ U, g<P>ListView1- &gt;Items- &gt;Add(); </P>, b- e/ t7 r  ?1 u
<P>  </P>
; m4 S( _6 p: H! G( g<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>- Q6 m0 m8 z4 E
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
* b  m+ t5 w$ j$ ^<P>if (n==0) </P>1 r8 D- H9 y' M( e4 d! n+ k& G
<P>{ </P>
9 W7 s+ N6 j7 `2 e5 Y: I; q<P>for(i=0;i&lt; m-1;i++) </P>- J- p2 L6 r2 ]: O4 d7 F+ Q
<P>for(j=i+1;j&lt; m;j++) </P>
6 i) o! E+ b7 O- ^# [) J<P>if(od) </P>
& O* M! e8 \/ x/ j# w8 Z( h# B<P>{ </P>
& i- f& G! d* A9 K' w+ }. ]9 k<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
) P( x/ U, u! f  e" b+ d<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>  S8 k2 E! a+ G) P4 f
<P>{ </P>
8 G+ e! }, j% C. y5 T4 B2 @; V<P>ListView1- &gt;Items- &gt;Item[m]= </P>
, u, F: P# Z" ?<P>ListView1- &gt;Items- &gt;Item; </P>2 ]$ Y) u. h8 B  M7 g. R0 R
<P>ListView1- &gt;Items- &gt;Item= </P>
6 p8 a) i- R/ b2 r2 S<P>ListView1- &gt;Items- &gt;Item[j]; </P>
7 |  D3 @; G/ O* D% i# u' y* `<P>ListView1- &gt;Items- &gt;Item[j]= </P>4 E7 @4 T6 ^* ]2 X3 A* \
<P>ListView1- &gt;Items- &gt;Item[m]; </P>. P" n9 X- M2 K4 j! W
<P>} </P>+ _1 S' j5 y6 S) B
<P>} </P>
8 @; N( ^0 l) L; X8 @8 U2 N<P>else </P>
. n  s# A! n0 c+ f) T<P>{ </P>
7 _) n# x' `1 {- v<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>) @- f4 @9 V$ p3 v6 _1 b
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>" ?2 _8 T% a4 g6 i* t' |% s
<P>{ </P>
, _: u& _6 x: P% ]* V( Y<P>ListView1- &gt;Items- &gt;Item[m]= </P>4 T# v+ i$ D: Z/ M
<P>ListView1- &gt;Items- &gt;Item; </P>
& F* ?2 Q* {8 s8 f1 B6 P, @<P>ListView1- &gt;Items- &gt;Item= </P>
% u) p: m6 D* A: C! @<P>ListView1- &gt;Items- &gt;Item[j]; </P>+ W0 B7 C8 N3 j3 X% ^8 m% H, ?
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
& v0 A- f6 l1 _* v. V<P>ListView1- &gt;Items- &gt;Item[m]; </P>
2 z0 V+ V- {+ w6 B9 Q! V<P>} </P>3 ]+ q; `; K; x. O  ^! r5 Z
<P>} </P>- g/ d1 L7 W  J. g/ c, q
<P>ListView1- &gt;Items- &gt;Delete(m); </P>5 Y" J+ I. E/ W6 [4 u
<P>return; </P>
3 M( r! N+ E9 c, n. S<P>} </P>7 p% J0 x  W* d8 k
<P>  </P>
' X' w# F/ `3 p# M<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>4 ~& D1 G1 H1 z" g6 Y' y
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
+ f3 k) ]% }+ v. U$ B/ ~<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>: D8 X, w' C- X! ]  S
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>; H; H9 W' b8 ~/ X
<P>ListView1ColumnClick前面即可。 </P>) b+ {( R+ D  i3 o$ c1 U
<P>#include &lt; vcl/dstring.h &gt; </P>
: Z3 [0 e/ H, I" r! A7 @% c<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
2 Y9 e' [+ j/ \# s1 `% T" N<P>{ </P>: Q9 D7 J, m, O. @. D6 x
<P>int l,i; </P>
: R& q* m9 H' S- t0 r<P>AnsiString qq(str); </P>( R( ~% B+ E* D+ |! e
<P>l=qq.Length(); </P>+ A1 A. n, Z% P* B$ Y
<P>AnsiString p(str); </P>
# F8 k- c( A( i, F<P>char a[]="\r\n"; </P>5 F1 Y/ W& O# e: D! E4 z( d' s% q
<P>int j=0,k=0; </P>: R. G4 s5 c- P# s' L2 F& C$ Z
<P>for(j=1;j&lt; l;j++) </P>
. ~: U0 \* ?- {8 [<P>{ </P>
7 i! {, N: Y* [# Y# K% o<P>i=1; </P># [, l3 i9 F& `) t& t9 V5 V4 E, R5 z
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>7 _, d# @  e. I" `: o
<P>{ </P>/ R; v- D! d! W
<P>p[i++]=qq[j]; </P>- m0 r& u- Q: }! @: S
<P>j++; </P>4 N( F, V: C/ F, _4 r; ~. S
<P>} </P>
) g  m( d5 B, }( `* U  t<P>k++; </P>+ E  [$ W6 @- r( X: e3 v& C2 c
<P>if((k-1)==n) </P>
8 ]: y. N: a$ L' z" A4 y- n<P>break; </P>4 s' I3 {4 w$ `+ D8 ~' {% }* l: x
<P>} </P>3 Y$ A' A" I1 ~  R4 n9 L) g
<P>p=NULL; </P>
$ a. ~  E$ H! {* p- D8 x<P>return (p); </P>
, @* {- [$ W! A* L* u8 S4 \<P>} </P>) r" [: w6 y; c) q
<P>  </P>/ O5 B; m% A" c
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>- s9 @" K! H4 t
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
- Z  D; p6 B' @* ?1 r; d<P>可完成对此项目的点击排序功能。 </P>
- b: W! ~+ n+ |- N- p0 o) x7 h<P>for(i=0;i&lt; m-1;i++) </P>
! f) b  Z" ^; v  l<P>for(j=i+1;j&lt; m;j++) </P>. W/ _: v2 V/ `, D5 O/ S3 O/ S
<P>if(od) </P>
% G0 X3 u. E/ c<P>{ </P>( g. j& E) O; J- h- ?* g% Y( k
<P>if(sg(ListView1- &gt;Items- &gt; </P>  s6 D: c; l* r
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>6 s: u+ O( d+ K/ m2 I# x* J
<P>sg(ListView1- &gt;Items- &gt; </P>. R# S# ~- g( B5 c* t4 ~
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>- r% ^* ]5 g% O

3 o+ w4 O! _5 i* e6 S<P>// ...以下从略 </P>  w# f- h' A1 `7 g$ {8 x6 C3 C  E
<P>  </P>
' Y2 I3 d6 I* X<P>最后,删除临时的交换项目。 </P>. n* Y+ ?) y7 Q/ x: k" ~8 ^
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
5 d3 z9 r  e/ g' n. D3 X2 r<P>  </P>
% B- M- k( k, i: }<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
7 z5 G+ R/ \$ e$ J5 L<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>8 M4 e+ D2 e, a: C7 ~+ V$ u8 u2 n
<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, 2025-5-12 11:58 , Processed in 0.531460 second(s), 51 queries .

回顶部