QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
" i7 d8 T8 g0 |5 r# }* I2 X<>  </P>  q/ V0 L9 Q7 t! ^* m% s  }" K" S! e( w
<>天津大学电子与信息工程学院 </P>3 @6 e- ^/ ~( ?; o7 [; }' v
<>宋天宁 </P>1 c- x% G  {: H! x
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
; i: |. C7 }3 ^<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P># M/ M- G# T1 v7 G' k/ ]- w
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>7 v, P& x' E3 s  g9 s0 O! @
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
6 D* Z* v; n( L<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>+ f  A: N% r# X! t+ L( |' ^
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>0 X2 j8 V) z& D0 A
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>/ c! C( t' G# w! v- N* J6 z
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>0 E3 I  f6 z* R9 A9 D
<>写自己的代码以完成这一功能。 </P>3 k' d' U( n# a# d" T! p' B
<>  </P>+ E6 F( v: R6 \! m- D
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
; N0 Z( |# _) J- D$ R<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>! G2 c: Q: f/ D  @3 J0 D
<>内容以升序排列。 </P>
' i* i3 @& y4 T4 p+ T- x<>  </P>
5 i+ ?2 l  n" w3 O4 Y( {<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>$ }5 a& b! N# L6 z. i
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>2 Z( L% [' }" l5 ~( ]9 H
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
, Q& W- S. \& y  l2 A8 A<>包含子列和主列上的内容)。 </P>
+ b$ T$ a# _& x6 i1 ~" \7 r# e<>  </P>& W8 Y0 N, g& ?5 d% _
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>& m0 p: Z- d7 U: E
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>6 }: @  W0 q* {  W" n
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
  ]2 M! C9 N# _: ]) u- W; P<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>& W3 t* x5 _! h7 e
<>  </P>
2 @" U! u7 r% J5 ?. Y! G<>  </P>
" j* t$ a( r: L* m9 Z5 m<>void __fastcall TForm1:istView1ColumnClick </P>1 d; B  Z0 R" S) `' [; i  X# @5 E6 k
<P>(TObject *Sender, </P>
' I: E9 r' v' t% @) v- G) B<P>TListColumn *Column) </P>$ O/ A; s) N7 }5 b
<P>  </P>5 [" I$ o% c1 P' k# ]: c; P: _! x
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
6 _# Q2 E) i5 O. S2 ^4 ?  O( Y<P>点击的列的信息。 </P>4 l( S- q; h- Y. C5 Q' L
<P>---- 下面先定义变量: </P>
: b7 u/ z$ b! s7 ]8 ?2 ~7 q4 u<P>  </P># h' P+ j7 X! g# O6 S' e
<P>int i,m,n,j; </P>- r$ B8 O# n3 C7 p, @& O8 H9 b0 F
<P>static bool od=true; </P>! ~  ?) L* c3 A! T4 {9 {
<P>od=!od; </P>/ ?0 ^7 V1 A5 ~. ?) w
<P>  </P>7 n5 X7 I- p$ R& q
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
1 N- c2 G' e- R3 u<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
8 Z2 [2 |6 M6 V: I2 P: ^% d<P>列表框中的总项目数。 </P>' ?% n6 m& Z8 J% q0 c. J
<P>n=Column- &gt;Index; </P>
- d" T+ R2 V3 G: f! Y<P>m=ListView1- &gt;Items- &gt;Count; </P>
# F4 N  k; `- T* ~1 f4 N+ [<P>  </P>
0 H* X3 a+ A5 Q: O<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
* @- I$ S+ c0 u( \6 Q' D/ w<P>ListView1- &gt;Items- &gt;Add(); </P>
! {0 O8 i7 P% l5 Z8 E3 n/ p<P>  </P>
/ Y) V4 P5 _+ ?3 X, F<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
5 t( ~5 A4 Q; W) }1 u% L# m) T<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
' W/ G3 Q! h! H$ Z; ]8 G1 U% c7 X<P>if (n==0) </P>
8 J* N3 \# S/ Q6 y0 C" d0 ~<P>{ </P>/ E" E& N: g% L; _
<P>for(i=0;i&lt; m-1;i++) </P>. S4 [! N( j/ L9 ^% ]
<P>for(j=i+1;j&lt; m;j++) </P>" j' [+ C/ D5 i
<P>if(od) </P>
+ R3 D% Y2 [2 n: B3 f<P>{ </P>
* [( ^. z3 Q! a<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
& k  z* M/ A/ X7 B4 ^<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
8 w: p( T/ v1 h<P>{ </P>
# p4 g; Y4 H, N* L  K) \3 N<P>ListView1- &gt;Items- &gt;Item[m]= </P>
  U# \3 g9 N( |<P>ListView1- &gt;Items- &gt;Item; </P>
1 z# X4 m+ s$ C$ i<P>ListView1- &gt;Items- &gt;Item= </P>
1 j" K. U8 b4 B1 x0 l<P>ListView1- &gt;Items- &gt;Item[j]; </P>
. p. c% Z- }' N7 w; F. B. }<P>ListView1- &gt;Items- &gt;Item[j]= </P>" O. s. B, R( R
<P>ListView1- &gt;Items- &gt;Item[m]; </P>) H9 K( L' m! D7 d5 r- Q
<P>} </P>
" x  b2 s" q7 C5 q- G) H# b<P>} </P>
1 A& D! L: {1 y# d<P>else </P>
7 p- O# b9 K# O) M& [/ c<P>{ </P>6 `8 W' w, i; A" }3 {
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
4 D' P. [, }0 T5 h+ a" F8 M<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
) \2 T- @6 T: i3 K6 A  t* t  P<P>{ </P>3 P6 B/ p+ p5 r2 c9 d
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
+ A: ]% Y$ s1 n+ k; [<P>ListView1- &gt;Items- &gt;Item; </P>( A5 i  i8 K% U$ o& }( d4 k3 e8 r+ w
<P>ListView1- &gt;Items- &gt;Item= </P>; |* c2 B! |' Q; h8 z$ ]
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
! o# c- E7 H& F5 P<P>ListView1- &gt;Items- &gt;Item[j]= </P>
2 }4 C) e- w! a. E9 d8 O<P>ListView1- &gt;Items- &gt;Item[m]; </P>
9 j3 }. P4 Q2 z- f# c6 s' i* u/ G<P>} </P>
# Y0 M1 p! O% C) p6 H6 U+ e<P>} </P>
! M4 l( `& o1 f% j0 F<P>ListView1- &gt;Items- &gt;Delete(m); </P>" J0 H( \' t1 o" G& b% M
<P>return; </P>
1 I# D) Y$ z& |8 f. O5 I; @<P>} </P>% O) [% e; F/ ^" K' a
<P>  </P>& u+ u- y5 I$ R- ?' _! |7 {; ?
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
: n  y) ?' D+ r<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
% @9 I, D; @4 H/ O1 e<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
- j4 i0 O7 j3 w9 x+ P" l8 X, L. h<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
5 n; B/ a4 i, V, F% r2 l<P>ListView1ColumnClick前面即可。 </P>
6 h$ V: t: S$ q<P>#include &lt; vcl/dstring.h &gt; </P>
$ [" D2 b$ V2 b, G+ y; J/ P& }<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
! r& m/ p) `* W/ m' w<P>{ </P>
, E7 I& S; \# f<P>int l,i; </P>
3 {( @, s! l  w, }<P>AnsiString qq(str); </P>) h9 \3 p! {- t" Q) q5 p% |4 k; q
<P>l=qq.Length(); </P>0 Q$ X- `/ s( s) E  o
<P>AnsiString p(str); </P>
$ {7 n5 F7 k3 V; w( r<P>char a[]="\r\n"; </P>
! J) y: t- e3 A+ X9 N0 b; R<P>int j=0,k=0; </P>0 x6 W9 d5 R" Y
<P>for(j=1;j&lt; l;j++) </P>9 S- A/ F; r( X4 f8 h
<P>{ </P>
( a; a5 c  ]6 t+ ?5 W5 N<P>i=1; </P>
* c5 m1 D3 h$ J4 u9 P<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>/ {( o7 o" P7 K3 e( f
<P>{ </P>, v& k8 Z) H( x: ^
<P>p[i++]=qq[j]; </P>' b5 B  |$ s' @# ~$ z; r( O, k6 k
<P>j++; </P>: K+ k$ X6 w$ v* R& H* i( Z2 _
<P>} </P>4 e& S3 e: [! a. z6 u
<P>k++; </P>
: B7 R& m; H) \: C5 Y<P>if((k-1)==n) </P>
# d! c/ O# E% Z# u+ o7 }: E2 ]<P>break; </P>
& W1 m% a& ]- X  B3 |8 E4 k1 ^<P>} </P>4 g! j" X! W; c$ R
<P>p=NULL; </P>
/ {, m( h6 v) V<P>return (p); </P>( `/ D: ?& q( A) J9 W! |
<P>} </P>
, M4 t5 s2 R6 a4 e% j- X3 `8 X$ |<P>  </P>
% t. X$ {& l$ B) _# K$ Y<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>( i0 r$ r8 c: p: w2 x8 h
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
; e( X+ j* O) [. G<P>可完成对此项目的点击排序功能。 </P>* S  T& N, c& c* U+ U  B
<P>for(i=0;i&lt; m-1;i++) </P>, V8 \" e, y  i& \) r9 k
<P>for(j=i+1;j&lt; m;j++) </P>  i' s# |  A' Z2 Q9 d, r
<P>if(od) </P>
3 _& b2 _7 {  a& G$ z1 v4 e) z' A4 R<P>{ </P>
8 E$ k& V; N( k0 f9 ?<P>if(sg(ListView1- &gt;Items- &gt; </P>- Z9 q. G1 o5 }. Q/ O
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
, V$ N: m0 X) v$ \9 ^+ W<P>sg(ListView1- &gt;Items- &gt; </P>
5 d$ [8 t* Z4 [, D; ]<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>) X" \/ {. n  u6 l' [

& `4 p/ H- u. M) `' H( O9 K# l<P>// ...以下从略 </P>/ _( K5 |' t6 \9 p4 J8 _: B
<P>  </P>, p+ b' S0 k0 }/ o2 l
<P>最后,删除临时的交换项目。 </P>& a/ F3 k1 M0 G" u  ~( @
<P>ListView1- &gt;Items- &gt;Delete(m); </P>5 j5 d3 W8 n# h6 a  J
<P>  </P>1 Q8 R9 J& @6 c5 N* D1 K3 n
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
# ]* W' t2 [5 f7 ]<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>$ ?. v/ q# G  d3 y
<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-7-29 16:15 , Processed in 0.454817 second(s), 51 queries .

回顶部