QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>9 f( k2 r( x, Z0 V8 a
<>  </P>5 B6 A1 {6 n( P" K1 x9 F
<>天津大学电子与信息工程学院 </P>
; D; h& v' M. Y2 P! A; z. p<>宋天宁 </P>
, I# J5 V9 t+ c! [<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>& x' V) B  w- f4 F, i/ t* f2 ^& z
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>. ~. U% ~7 l  q9 r$ k# |9 l
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
# x% L; c  X/ h: e<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
/ N; o" k7 h' L9 X% s<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>; U* N) ~* V5 ^7 a$ V  F/ a' x
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
: X9 V4 L3 y8 ~$ [& M<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
, A6 z' |' T  f' }<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
/ t3 m% ?, a$ z) t" c<>写自己的代码以完成这一功能。 </P>, {# V, ]' k- I# T5 T1 p
<>  </P>
* y+ ?3 ?" O, D! ^! Z; w& r, q<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>) f5 `* ~& Y+ t0 [$ G5 p
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
/ `' y- x1 u& i* T( P3 ?/ h% [: V<>内容以升序排列。 </P>
( |& C; p% i( f/ u* b: r<>  </P>4 w; J; a! M" T- B. S
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>, X' T- q* w2 D7 p
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
5 c* f8 T/ p  y1 w. C<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
2 Q& ~/ Y3 [& Z+ b8 N<>包含子列和主列上的内容)。 </P>  X( ]& c( r5 V
<>  </P>
. ?9 {. _8 n9 I/ E& \/ |<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>  L3 U3 T2 y% _7 L7 F9 q9 |
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>; M# G7 V3 m* ^8 j! o; o3 D" V% g
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>( b4 [2 a1 Z0 m7 p# S$ `# b
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
& g2 |0 p9 ]3 ?/ ?, L* s: j5 B<>  </P>
6 Q  o1 @3 O, k3 I' B! _5 x<>  </P>
+ Q" j6 b7 C# g  r, G8 G<>void __fastcall TForm1:istView1ColumnClick </P>
7 S6 I5 F! c! ^$ `; d0 a- S<P>(TObject *Sender, </P>8 O- ?' J8 E: l7 N% _/ w
<P>TListColumn *Column) </P>
! V5 t6 I2 a5 d<P>  </P>
) X9 ]8 ~' ]  d) o+ Q<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>" x8 ~1 M4 U0 P2 w
<P>点击的列的信息。 </P>7 h; R& z$ m  j' a
<P>---- 下面先定义变量: </P>
# Y/ p9 s) H# k+ i<P>  </P>
& k0 w6 _6 z" j* d<P>int i,m,n,j; </P>; f- C6 [6 E/ s: j% L; c9 `
<P>static bool od=true; </P>
/ u& m% m( x* p# J<P>od=!od; </P>" g. E, j0 d+ T  X
<P>  </P>! j3 N1 q+ X0 w  i1 A1 n0 B9 {
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>) _9 F$ \6 E; |1 h/ K' l
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>' X3 b. B: o$ `6 U2 I
<P>列表框中的总项目数。 </P>
  e3 ?3 g& d, K<P>n=Column- &gt;Index; </P>
7 P3 |; s( W/ L; v<P>m=ListView1- &gt;Items- &gt;Count; </P>! {0 _" e( X6 r0 R7 t
<P>  </P>! L/ s, r; L  ]. F
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>  O2 ]7 K6 Z  A* R) g7 a, I, s$ Z+ E, y
<P>ListView1- &gt;Items- &gt;Add(); </P>( F* c  v( i& Y4 [/ o
<P>  </P>
2 Z% K3 @* ~3 l- s, V# a<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
0 J& i" `" H2 o, ?$ p+ g0 A2 U8 V+ y; o<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
; q: Q. z$ p; }/ |& _- P! a, g0 @<P>if (n==0) </P>( v: O& A/ R, r* ^+ O4 K- E+ M
<P>{ </P>
* S* J6 m4 Y" |- C" f<P>for(i=0;i&lt; m-1;i++) </P>
3 w  @. F+ R* \/ P2 [  h( \1 J/ }<P>for(j=i+1;j&lt; m;j++) </P>
1 `# x+ D' s7 @# \4 H% d$ G& i  g' |0 H<P>if(od) </P>) F. H8 p# |0 ]
<P>{ </P>
- P$ m" ~) s: G& c5 ?<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>3 ~/ V: b- ]/ L. y/ a
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>% I( Q( q  U5 u- c( |8 s$ S5 n) d
<P>{ </P>
) O1 a4 s! y$ h  s/ L/ q& k<P>ListView1- &gt;Items- &gt;Item[m]= </P>
  V3 u# F( T% o; Q<P>ListView1- &gt;Items- &gt;Item; </P>
8 T9 l  p+ y# {. v  J5 j0 m<P>ListView1- &gt;Items- &gt;Item= </P>
/ f- s! x- L5 \0 [<P>ListView1- &gt;Items- &gt;Item[j]; </P>
; k6 U' x  \8 y8 `1 M0 _) A" ^<P>ListView1- &gt;Items- &gt;Item[j]= </P>
6 D& {% z. K' N: D5 J+ ]<P>ListView1- &gt;Items- &gt;Item[m]; </P>6 v+ N8 _- }- Z' O' V
<P>} </P>
& ?4 m. d* c( W0 U- y, K6 L1 q<P>} </P>
0 z' m6 X" b3 g# y. c0 _<P>else </P>
$ D6 c7 ~3 F2 o. p% i! w& z1 P+ }6 [<P>{ </P>
& @3 K3 g; y# O8 l<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
+ U/ C$ r4 [! C% s6 Y& s4 P<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>0 K. s1 s: s0 N" @
<P>{ </P>8 n$ l5 {' V" G* a- I- O
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
  m8 ?: p% M) s6 P/ R: u9 d; E<P>ListView1- &gt;Items- &gt;Item; </P>1 H. L. @. s! }% K  o2 F
<P>ListView1- &gt;Items- &gt;Item= </P>
& {9 r, J2 W* ~<P>ListView1- &gt;Items- &gt;Item[j]; </P>1 }4 Y' ?! V2 k8 \0 m
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
0 X0 ~! N" T6 H, k* l: X<P>ListView1- &gt;Items- &gt;Item[m]; </P>
8 x0 F8 U; g' n) U<P>} </P>
! j2 [2 A3 r: p: H+ w$ ~0 I<P>} </P>1 W6 Q3 p, t- k4 |. d2 \
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
. g! ]6 T: A5 {) j+ r<P>return; </P>& q! _2 x& Y' J
<P>} </P>) u1 }. |( P9 B% T$ [
<P>  </P>
$ n, E. a  a% T: f2 G( a<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
8 @) I, C* ~/ J' Y& k<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
- [' h9 F! x8 J9 ]<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>' Y/ F: w! `) I) l% `5 F
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>1 d, K1 E0 h0 R8 s7 P
<P>ListView1ColumnClick前面即可。 </P>
) e: z# L* ~+ b1 G4 R) _# s9 s, ~<P>#include &lt; vcl/dstring.h &gt; </P>
5 }  H, H; \: q- |; q<P>AnsiString __stdcall sg(AnsiString str,int n) </P># h, `) R; c# b6 X- ^2 l
<P>{ </P>* o; ?" Z0 `, K; ^% c* r
<P>int l,i; </P>' c, n& D  C+ f5 D/ _9 ?
<P>AnsiString qq(str); </P>
4 D0 I& e7 ^$ X0 |# S: y# b<P>l=qq.Length(); </P>: m& W9 B+ c3 Z) l! l
<P>AnsiString p(str); </P>. E3 L3 D0 E' N+ b. s& h' |) N; D
<P>char a[]="\r\n"; </P>0 _+ D# I6 O" n+ J" K
<P>int j=0,k=0; </P>
" g: j7 _0 ~, i. |+ ]) h8 R<P>for(j=1;j&lt; l;j++) </P>
3 N+ ^! M$ J2 s& H4 r: w" ~- L; a<P>{ </P>0 P+ T9 B7 r- n+ P4 u
<P>i=1; </P>
5 |, @5 F' l4 Y7 g  \! s<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>) x7 S0 L& Z# Z+ s# o8 J
<P>{ </P>
' S) {8 r2 U3 m- d<P>p[i++]=qq[j]; </P>! t* a1 ^7 G7 p2 o
<P>j++; </P>% }4 Y# j  `4 n1 R
<P>} </P>) f6 h5 T% S+ z! {' @
<P>k++; </P>
8 k2 \0 Y! d5 C0 ~6 i# u7 [<P>if((k-1)==n) </P>
" Y) q' y9 M/ O' i& U3 w<P>break; </P>
( j* H$ @8 C1 l$ B- U& G, k<P>} </P>  ^/ w6 E+ w& X7 G1 s
<P>p=NULL; </P>) A6 ^6 v6 w7 r; o( i
<P>return (p); </P>
; e$ ^7 w! A/ j9 ^4 u<P>} </P>( q; H) J) `% L# X) m6 F
<P>  </P>* t% P2 s+ f1 T9 H+ B  F
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
) M/ Z7 A% T9 V1 H/ n. o& ~: M# r<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>: p2 w& k. J4 I5 X
<P>可完成对此项目的点击排序功能。 </P>
: \% q9 _0 |7 B# p1 h) g<P>for(i=0;i&lt; m-1;i++) </P>
& F6 S" C( {$ ~+ n  u  ?7 [4 m<P>for(j=i+1;j&lt; m;j++) </P>$ t, M2 X/ @8 {# O9 L
<P>if(od) </P>
4 [1 J6 ~' a) c6 t<P>{ </P>
7 v/ p3 e+ N  L2 x8 _' T<P>if(sg(ListView1- &gt;Items- &gt; </P>) F- f( A3 C% u( g9 `
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>* e( ~& `, A2 J. a# Q0 u
<P>sg(ListView1- &gt;Items- &gt; </P>$ k& E' q/ K& Q$ H& t; ?
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
- C2 A- C, \1 ~! w4 ]: C( g9 M$ k5 |
<P>// ...以下从略 </P>: y8 t; o! n# e; ~$ _! k2 e0 J" P
<P>  </P>9 ~4 d( n$ w- W1 l: ~
<P>最后,删除临时的交换项目。 </P>- P! X7 W4 f& m( s4 d
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
# {" ~" D  A3 Y# ]7 [) G' W<P>  </P>8 L5 I9 Z* s2 m
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>7 A& Z: M7 F& a# R
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>1 g9 ~( Y  E5 w- w( N5 ^- 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, 2026-7-18 09:39 , Processed in 0.397260 second(s), 52 queries .

回顶部