QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
' e) ^1 ?1 ~* I+ ~<>  </P>3 c' p1 l' h  b
<>天津大学电子与信息工程学院 </P>
2 f, z6 y6 h: d  J3 r<>宋天宁 </P>/ h$ Q" c9 G. ^# j$ V8 a
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>; U& p( U9 I$ V1 D
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
+ S5 z* [) [) J' f. W0 J" J; f<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
; o. G$ v# L' t. V: f  ~4 V<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
! K9 z$ A( r& Y% q<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>. h6 h$ W& }- Q/ f
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>- b, o+ ]8 B: {- f: E8 Q% i
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>. g/ x( Q/ V' m6 t" j2 w6 k9 }; f& V
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>9 Q+ G" ^) |, U  e
<>写自己的代码以完成这一功能。 </P>
- z- k6 e& N4 c9 m1 V( h% L<>  </P>9 N* _3 ^6 y# p) W, [5 {
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>" E# Y3 w$ w7 ]$ N8 W3 z1 W
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>+ f1 I. Z' \; K- T1 T
<>内容以升序排列。 </P># z  ~5 [9 G7 x0 {: W6 ^
<>  </P>4 P  ^# r) f' s+ A3 a; U0 \) `
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>% @# \* x! d6 u. }# a* |
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>; z" U, O, B+ T+ J! d0 I6 ~" Q
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>: L9 B, f" B* [5 I/ u- s
<>包含子列和主列上的内容)。 </P>( b  E; d: D* G+ v
<>  </P>
1 M) t& q8 j8 g* T/ x<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
/ G4 ?, ?# `3 O* m2 P) r, [<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
4 _4 K9 w5 G5 K) i<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
$ F/ ]: m& A, G7 b0 L<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>- w$ U0 b" T2 y  G: {; m5 u
<>  </P>
! t. z( p! I* W! N: z& Q* X4 ^, e<>  </P>
0 ?* I* F7 b7 g<>void __fastcall TForm1:istView1ColumnClick </P>
' ^" A+ D8 Z: ^! r5 I+ Z<P>(TObject *Sender, </P>1 _0 n' H- Z- }9 u0 ~
<P>TListColumn *Column) </P>
  G5 P0 y1 ?2 `<P>  </P>
% u3 Q% L* U# K<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
. w1 j4 @2 p* Q2 Y$ D* w! q( N' j<P>点击的列的信息。 </P>
7 g( v9 p# K( v; K' D; W- ^* d<P>---- 下面先定义变量: </P>- Q) r9 v5 Z& m( ?# h
<P>  </P>
6 a1 |$ d3 v; a; i+ S5 t& V$ v7 T<P>int i,m,n,j; </P>
" D6 `; I- \' w: O<P>static bool od=true; </P>
7 ?0 M7 D/ M9 j* _, a: Z, T- O<P>od=!od; </P>, u) d: \+ Q+ Y' J( c
<P>  </P>
1 T" y) \% p% E3 X3 F* Z! G<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>+ U4 K7 n" f. e7 Z( \
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
1 k* T3 j% Z% g+ f) B& |<P>列表框中的总项目数。 </P>: ^6 x$ V( l) D0 x5 K* }. ?5 X
<P>n=Column- &gt;Index; </P>, m- Z* X  R1 i+ N
<P>m=ListView1- &gt;Items- &gt;Count; </P>
7 i) z, g5 [; @3 z<P>  </P>
( {$ X* m, o) B- M% D5 w$ ?0 F<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
0 ~  V' X: J$ y1 S+ a3 B; Z<P>ListView1- &gt;Items- &gt;Add(); </P>
; ]" `+ s% w" u# U<P>  </P>% P2 |# b  o; A3 b4 e8 _& f( P$ _! ~
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>; y0 h) ?& g$ f* C% Z3 F3 x
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>6 @/ y+ D4 m" _
<P>if (n==0) </P>
3 K6 C* Y0 N3 {. M# U<P>{ </P>
( f1 A0 h2 M5 F' ]8 U: ^5 h  m<P>for(i=0;i&lt; m-1;i++) </P>
: y5 }7 a  P  ^- X3 V4 d8 I, e<P>for(j=i+1;j&lt; m;j++) </P>+ ~" ~0 E, r# T8 a: G/ U
<P>if(od) </P>
3 u7 W9 h1 I& o4 @. R# D<P>{ </P>* ~* m2 T" Z# G- Y
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
. x) x7 O) M  `6 ]& d<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>7 |1 P0 N  r. X! M
<P>{ </P>4 p" K% ~( C  q$ d0 U) T. c- C+ I" {
<P>ListView1- &gt;Items- &gt;Item[m]= </P>  u/ D1 \" @' I8 r; I6 r$ v1 O
<P>ListView1- &gt;Items- &gt;Item; </P># n2 y3 i1 L1 h4 Y' Z$ v$ g
<P>ListView1- &gt;Items- &gt;Item= </P>
  d6 |8 D: [( D<P>ListView1- &gt;Items- &gt;Item[j]; </P>1 Y: d) s" |- Q4 Y/ {
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
$ ^6 ^$ t- ~4 f3 r& D<P>ListView1- &gt;Items- &gt;Item[m]; </P>
8 L( r2 o% E: l<P>} </P>
0 {* k! u; g1 D% t  z<P>} </P>
) e# s) G$ H$ m, a) c# R5 g<P>else </P>, h" `6 J$ J9 M" V0 y* ~; e) }2 N
<P>{ </P>1 f9 w# U, M) t& U/ A; V5 B
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
* \& F; m" o9 g! t, k! h<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
% t( V; l+ t: W+ j1 a3 P<P>{ </P>* M+ x+ e5 g! I
<P>ListView1- &gt;Items- &gt;Item[m]= </P>4 Z% ]. q: w% A$ `, p. o8 e6 ]
<P>ListView1- &gt;Items- &gt;Item; </P>
( J. I7 C0 J' E3 x" y# R& E<P>ListView1- &gt;Items- &gt;Item= </P>
8 ~( y6 \3 r. s5 n6 m<P>ListView1- &gt;Items- &gt;Item[j]; </P>
" m" D2 y. Q# ^# \<P>ListView1- &gt;Items- &gt;Item[j]= </P>7 I# V. N1 ?  e2 A5 u) n) ?
<P>ListView1- &gt;Items- &gt;Item[m]; </P>$ y3 q: T. o1 `
<P>} </P>
$ W4 \3 _1 a( U; h- B* X<P>} </P>
0 s" i; H+ ~, S8 V* B/ X" Q9 S<P>ListView1- &gt;Items- &gt;Delete(m); </P>) `3 G5 |, B3 z4 A" P( L6 S6 e
<P>return; </P>
6 l" }& ~5 B. m8 _<P>} </P>
- m; ^: {8 b) y<P>  </P>
' ]& {" u" Z6 E! {( ]' G7 `1 V<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>, R8 F# k5 ~# E) G+ o- S& P1 b
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
% h: Z2 I0 _6 J; h& O. I. c<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
+ }0 d+ A( [, X1 L<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
. ~6 P) H. o) h% K$ [* }<P>ListView1ColumnClick前面即可。 </P>
  \7 I/ I3 q0 Z- E$ a<P>#include &lt; vcl/dstring.h &gt; </P>0 k' ~; u/ j; x* J8 s
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
0 N" @+ ?% }  j4 v. M  Z# L<P>{ </P>- n4 o) g4 R. q
<P>int l,i; </P>
" @8 Y. X' {; o<P>AnsiString qq(str); </P>
: N# B7 {& T; z* ^, L<P>l=qq.Length(); </P>9 S* P& W8 U* t1 n
<P>AnsiString p(str); </P>* O& c4 q; n9 I$ X" h" N0 o
<P>char a[]="\r\n"; </P>6 |+ M- S% F8 H2 X( d" W8 R# J
<P>int j=0,k=0; </P>8 o* ]* d" a# t. A1 g
<P>for(j=1;j&lt; l;j++) </P>0 o: }! L8 E+ H" A$ G' S( o# v# |
<P>{ </P>
, e& I7 M0 H1 U! w6 j<P>i=1; </P>- N. F/ r4 O2 V6 M% \
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>$ P% l) E/ @' w" C# N1 o4 D9 r
<P>{ </P>
' z9 X) o  }9 k" h# F) {2 Y& I<P>p[i++]=qq[j]; </P>
( `* K) z' P1 ]: Y0 z<P>j++; </P>+ I1 f; Z# K& h/ b% V/ N
<P>} </P>1 L; H. i0 s7 {2 d1 }% S
<P>k++; </P>% W: g: f- j7 K
<P>if((k-1)==n) </P>5 L; k5 U. \* Q' F9 A" B
<P>break; </P>
# Q* H, O2 d/ G<P>} </P># @0 R6 a0 K, e( I2 E5 N; O( }$ F
<P>p=NULL; </P>
& A( r3 W; @- s  m3 s: ?0 s<P>return (p); </P>4 l) n' a  e8 f
<P>} </P>
- U2 d! r- P# l<P>  </P>. _1 x/ h2 J5 C& i4 t
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>, P/ J7 f2 N+ [/ \' F" X" a
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>$ w0 s6 t" Q( n+ n/ P# X% F
<P>可完成对此项目的点击排序功能。 </P>
# b0 \# D  B3 f% j+ r8 P<P>for(i=0;i&lt; m-1;i++) </P>+ q* A, I9 ~5 H8 A1 T  h
<P>for(j=i+1;j&lt; m;j++) </P>
( H  U; H9 k4 @<P>if(od) </P>
: B. u% |# g9 ?+ s1 f. s<P>{ </P>7 v7 y8 e4 V5 H0 D; v! y5 e# O: b
<P>if(sg(ListView1- &gt;Items- &gt; </P>, f6 v! f/ I: d% X
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>, I0 v5 U, i% J$ `$ X2 z
<P>sg(ListView1- &gt;Items- &gt; </P>! Q- H& E7 q& R2 J- _. E5 _
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
+ J% N4 Y' r' W0 n% p( P+ O5 X+ Y& a* R8 _7 c
<P>// ...以下从略 </P>3 o! G2 P" E  b) q8 V
<P>  </P>0 R, O& x: l2 L: k$ f$ ~
<P>最后,删除临时的交换项目。 </P>) a2 d5 @( l3 e! ^: D
<P>ListView1- &gt;Items- &gt;Delete(m); </P>; b  h6 [: h. t8 L; Y/ C
<P>  </P>
* Z& L$ I2 j2 y  T' V) r! z<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>8 u; ^( o2 _( ?9 O
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
% l; K+ ~+ Q7 `8 E, 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-4-19 00:56 , Processed in 0.408177 second(s), 51 queries .

回顶部