QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
% T6 y6 z$ E) E<>  </P>
/ [) |  A5 g4 r+ p<>天津大学电子与信息工程学院 </P>
3 T7 E6 h5 b* J" |<>宋天宁 </P>
' p- d8 E6 i" X5 D7 v<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>5 B9 i9 W9 o) ]2 ^2 e
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>+ c, O. s  i, y/ L$ X% W2 g* E4 x
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
) Q: X& |" `8 h* y% \<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
$ u( g: U( b1 b9 P7 H+ o+ |<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
  E; G; N$ x* m$ k/ |<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>; e; G% o0 a8 K
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>; `/ Z$ M( U$ B- }
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>9 N  y* x/ ^; h" @
<>写自己的代码以完成这一功能。 </P>; B6 U! O$ }" G8 ?0 y+ Q6 g
<>  </P>
* E) n7 r1 \  |6 D( g<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>4 J7 ?! T9 R$ P1 L% S- t
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
% O' a5 R- @( f* x& X  {* P<>内容以升序排列。 </P>
$ a! ^& d+ M/ ?: \# R<>  </P>+ t2 ^( ]$ x5 o% _
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
$ j( W' f. R! b7 j<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>: L$ X9 x( j) @6 _5 F
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
6 i) a# |# S0 y6 O<>包含子列和主列上的内容)。 </P>
; ^. @* Z$ G5 }2 m% H+ E" [0 S<>  </P>. D7 E) A" j6 x% H+ L) s7 e. _
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
. p, e3 ~* r. Q0 I! U<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>: x/ C' y: r- K
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>/ t  K+ ]! A" Q1 D: p2 R; ]
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>9 F' y4 x: \6 r* s3 o" m# c& O3 d
<>  </P>: C# T! o! v, b$ n- N9 ]5 L
<>  </P>8 E: ~7 p2 _) c+ _
<>void __fastcall TForm1:istView1ColumnClick </P>7 R* l0 a/ K" S% M
<P>(TObject *Sender, </P>5 O: ?2 N1 K9 `# }6 k4 g9 y
<P>TListColumn *Column) </P>! y( y/ u+ p# t5 P3 _3 ]; J# I
<P>  </P>
( u* o( Z. \7 O8 x/ ^<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>1 `! @/ h& ~! B
<P>点击的列的信息。 </P>
! n9 N# G5 m3 Z  B<P>---- 下面先定义变量: </P>) C  x: J4 R4 v# Q& y% O/ i; F  t! K4 U
<P>  </P>' d, N& N# C% }. |6 `$ M
<P>int i,m,n,j; </P>& K: q% W5 H/ r+ g6 t0 T
<P>static bool od=true; </P>& f" ~; T, m. {- T5 I
<P>od=!od; </P>% ?9 l* Y1 W) Y7 @6 B! I0 P
<P>  </P>) c& X8 O/ Z, q% w9 Z5 w
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
3 y7 D8 {  k' ?/ A& D<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>; Q/ L3 [) n, |9 j. E" B5 f
<P>列表框中的总项目数。 </P>
) l) K2 l' }  q* N4 A<P>n=Column- &gt;Index; </P>
8 c2 n- y' s3 X1 h1 e<P>m=ListView1- &gt;Items- &gt;Count; </P>
$ [- `) P' ^- {( y8 N3 M6 `<P>  </P>
+ ], Z$ j! S7 ?<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>0 ?" r8 {. O/ l2 s, s6 y( q
<P>ListView1- &gt;Items- &gt;Add(); </P>
- \: o" W9 z, o/ b" ^) G- x7 L<P>  </P>. C+ d7 r! ~5 B, p5 _) G
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
% Q& Y% P( E) ~- I<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
( ?/ m3 s  s; [% g<P>if (n==0) </P>2 ]; d* K9 l8 W- `7 P# l
<P>{ </P>
. M% D) R0 w3 L$ A<P>for(i=0;i&lt; m-1;i++) </P>- g4 U  x" I; D! S& g
<P>for(j=i+1;j&lt; m;j++) </P>
; I% T+ ~2 ]( }5 A# Y0 {<P>if(od) </P>
. t6 q9 X5 h. P- V5 l<P>{ </P>6 C6 [" c" c( M1 e+ G
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>- C0 v5 Q' Z7 e0 V1 z
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
) a) e, [4 F1 i2 B$ f' v: t( }<P>{ </P>* I4 U0 G  `/ U: l+ ?& m& S
<P>ListView1- &gt;Items- &gt;Item[m]= </P>8 r( l9 V- K( n( u% @) n! x9 m
<P>ListView1- &gt;Items- &gt;Item; </P>) N. b$ ]5 i) p
<P>ListView1- &gt;Items- &gt;Item= </P>' W6 G* {3 O; x4 D" c
<P>ListView1- &gt;Items- &gt;Item[j]; </P>, ]# o8 S6 `  u' L3 x8 E
<P>ListView1- &gt;Items- &gt;Item[j]= </P>. Q4 U) E" ?9 R$ Q( y8 }9 ~
<P>ListView1- &gt;Items- &gt;Item[m]; </P>' N/ i, H, Y2 }8 k: ~2 D
<P>} </P>% a  K+ {/ p4 o1 v( Y7 p
<P>} </P>
  g: L- I% Y+ F, K: S- S* d% s<P>else </P>8 m) w" A0 C  H* ], J
<P>{ </P>
7 H0 Z% H+ g& {; ~' V<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
8 C% j  N. q* C4 W1 `<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>5 t$ D+ m0 a! Q" K* D. m/ C
<P>{ </P>
9 y3 x3 n* c: x8 A$ v. a<P>ListView1- &gt;Items- &gt;Item[m]= </P>
  K) k: l6 Y: C+ ~" Y' s$ f5 h<P>ListView1- &gt;Items- &gt;Item; </P># Z$ `' c$ R3 E* r
<P>ListView1- &gt;Items- &gt;Item= </P># \8 V% j1 J3 D6 b
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
! T; k# H, d4 x9 s<P>ListView1- &gt;Items- &gt;Item[j]= </P>  x" j# B- O# G# t. y
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
6 \6 m  q- s+ q<P>} </P>& f0 I! z3 _! s6 o( _3 r9 o
<P>} </P>
" z  R$ l9 q, ^<P>ListView1- &gt;Items- &gt;Delete(m); </P>0 u& L- \4 T# W& a) r: |( F
<P>return; </P># p; s% `6 k. K  P7 J4 c) m$ Z* `" Q
<P>} </P>* Q+ S  ?- _, ]+ i- D: c
<P>  </P>
7 @3 N7 p! M( b) x7 V! g' I; o<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
% r( Z; {1 X" A, g<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>3 V8 P! k  B9 |, ]/ k# P2 a1 N
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>0 [* @# r9 V/ b1 q7 R' e6 z; ~
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
9 R) Q* _$ Z+ n  Y<P>ListView1ColumnClick前面即可。 </P># e& ]- O) R5 W/ e+ j+ h5 `* o2 \
<P>#include &lt; vcl/dstring.h &gt; </P>
0 x% C, I; e( ~6 I  {<P>AnsiString __stdcall sg(AnsiString str,int n) </P>) {+ s! V1 I& F
<P>{ </P>
- @8 Q& o) q# D% o, C9 K<P>int l,i; </P>$ G4 _9 s  c) ^; B& X* y/ y% k6 c
<P>AnsiString qq(str); </P>
; Y( [+ R& S+ ~% X: r! r2 h<P>l=qq.Length(); </P>0 q# d4 O3 I! m# X% U% D( w9 f
<P>AnsiString p(str); </P>8 z  e4 I# `; E' \, D
<P>char a[]="\r\n"; </P>& ^: C8 M' c: ?" D
<P>int j=0,k=0; </P>
4 ~! N8 e* q* e( L6 U<P>for(j=1;j&lt; l;j++) </P>3 `5 g1 G$ C" }0 N* a& v) E, f
<P>{ </P>: e8 U, R" Y; y
<P>i=1; </P>
  K6 ^8 o7 [9 y2 p! C<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
) H2 K0 K& r3 C# l  H1 u' S<P>{ </P>
! ^  e& [2 q0 ~! v' {2 [" h, G$ k' u% n<P>p[i++]=qq[j]; </P>1 |) w- t5 M3 S7 j+ m
<P>j++; </P>! A; S! P: A. ^0 I5 ~' G
<P>} </P>' z' `% F! y. ~! k
<P>k++; </P>
# O' U6 Z. I* z, Y- T<P>if((k-1)==n) </P>
; C8 a" X. H! V' v* y" N3 j0 k<P>break; </P>5 g1 B3 e/ C$ ~3 Y
<P>} </P>
2 Z8 D2 M) U! y" w<P>p=NULL; </P>& E0 c+ M5 e# o1 S' f) C
<P>return (p); </P>9 V5 N2 t8 l! v1 i% `
<P>} </P>
# l: v: ]5 r. U: {4 p7 h. w* N<P>  </P>
- v6 Y0 r, P8 e5 ?<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
$ T$ z, h  m0 U" o9 A3 z<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
* U7 h1 x" B" X<P>可完成对此项目的点击排序功能。 </P>3 o2 M8 c( b' o' ~
<P>for(i=0;i&lt; m-1;i++) </P>
$ t* Y8 ^! u' Y' f<P>for(j=i+1;j&lt; m;j++) </P>' s$ h6 d' S& {2 J& y2 M3 g. m" ^
<P>if(od) </P>% q9 |& Y: Z9 z3 E
<P>{ </P>" u3 |8 i+ c( H" E; D
<P>if(sg(ListView1- &gt;Items- &gt; </P>
. @$ `$ V1 B- B0 w  B<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
1 p' g* Q/ ]6 r9 A<P>sg(ListView1- &gt;Items- &gt; </P>  J6 Y/ }+ k6 N. j( X8 F
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>6 P$ d% W9 m- B4 |, T) V' X
0 v- A% @4 |5 m2 N7 d. \
<P>// ...以下从略 </P>4 K6 [# O) {; N' w- R
<P>  </P>* U# b& d3 j; {7 f7 A% k
<P>最后,删除临时的交换项目。 </P>: W( E7 K, ^7 Z( C# C7 g0 O! `- H
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
3 K9 L* `; ]6 U6 I& i% Y1 T$ h* o<P>  </P>
: F; @0 G  i( W' \1 Q8 \2 y; E<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
" r: I# u! |. t  S# @) c! X<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>7 w8 Q+ e4 W( D) t2 D2 q8 O0 N/ v, |
<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-5-26 05:45 , Processed in 0.310387 second(s), 54 queries .

回顶部