QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>' @$ I7 J5 B5 P# O1 h/ S$ P
<>  </P>4 m2 c. {+ P$ k8 t: s
<>天津大学电子与信息工程学院 </P>
2 z' L3 I, M7 r  P<>宋天宁 </P>
- y& \, d" w$ P6 B: |* I<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
3 ]) ^5 x2 q; z  C7 |  Z: k<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>6 R8 `. `9 d! m
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
+ A1 }2 D, f# J* \0 E8 S9 L( d<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>/ H' y: v( A( m( g: W
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
# e/ U) b( C# ^8 ~! N* a# k& s! {<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
* Q/ H0 p. z0 |  @4 O+ W$ N<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>3 ]* J; @( F/ R- k- q
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
  \) d4 e" G6 M& P# @& x' w<>写自己的代码以完成这一功能。 </P>8 m- `, Q4 O0 P: I3 Q7 a6 q2 L
<>  </P>5 M* ?' N; S0 K9 v6 \+ k
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
3 m- g' U7 o% c: y- a" z# v& ^<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>$ s" Q3 p% ~2 a  n" \
<>内容以升序排列。 </P>0 n$ i3 X0 j. s; F1 }2 F3 ?
<>  </P>
, K+ a# o3 L: j2 e9 ~<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
1 r5 d. v0 V: M, R<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
/ w. l. b! Z% |; d$ p/ G<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
0 A- A$ @0 R4 G& q1 n- ~<>包含子列和主列上的内容)。 </P>
6 G" p& m; O* D2 c: p1 x* g1 o<>  </P>) \' _) p. Z  E* @
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
+ J& `) _* n( D; V3 F# D0 x<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>1 x/ C. F) R- D1 a/ o
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
1 Q7 X2 e' M, j. r<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>* B/ U2 b( d- \' h( C6 T
<>  </P>  g- ?0 \: X6 e/ X
<>  </P>; A9 Z5 R9 ~- E& ?
<>void __fastcall TForm1:istView1ColumnClick </P>- y4 w3 S3 u0 [2 W- u+ \
<P>(TObject *Sender, </P>
3 X" i6 U% @$ |<P>TListColumn *Column) </P>
3 H6 f; a5 D2 \. w<P>  </P>, G+ k% {3 c& @, y" H8 b$ Q
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
* d8 H1 `$ t  o% H<P>点击的列的信息。 </P>4 T+ l3 ]  E! p
<P>---- 下面先定义变量: </P>
% ]1 z, [& v) C- p1 j<P>  </P>& L% B. S7 y  z7 e( {" o$ a9 ^2 O% i
<P>int i,m,n,j; </P>. U4 ^! L2 R/ ^# Q+ q0 T  n1 a
<P>static bool od=true; </P>
$ e* |1 B) m0 l( h% e<P>od=!od; </P>5 I; t6 m) d' a( |1 U* `
<P>  </P>
" A8 p$ ^' m( C! u: R" a' K<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>% ~' D* O; I4 Q9 Y% F
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
% i8 R/ c" |2 g% l<P>列表框中的总项目数。 </P>) T' c9 `/ R3 j+ [9 y
<P>n=Column- &gt;Index; </P>+ X* s6 `8 S7 ~+ {* c5 m9 Y
<P>m=ListView1- &gt;Items- &gt;Count; </P>
& B$ b) v+ t( ~+ C. Z<P>  </P>
. n& A; {) P- K# m4 r+ x( g( u<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
. |- a, |2 _' M1 Q8 v<P>ListView1- &gt;Items- &gt;Add(); </P>; P) c/ f* d. F" j% s
<P>  </P>3 W9 _  O* z# e6 P& R  Q
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
6 f+ d  j# s2 `$ b<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
; _: _. Z2 o) X  @2 \. ~% i+ P! q+ i( |<P>if (n==0) </P>6 a- p4 z  _+ t$ l& L% d
<P>{ </P>  t  L1 M& F# E! }
<P>for(i=0;i&lt; m-1;i++) </P>0 r2 G0 U; l, }% L* K
<P>for(j=i+1;j&lt; m;j++) </P>- j2 e+ t! W/ Y" c% W
<P>if(od) </P>) V  U% j) b6 J
<P>{ </P>
* `% w( i3 I# j7 l, |, B/ X7 N<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
! m) _$ ]4 S5 {* Y( J3 e3 e/ T4 y9 r<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
2 [, _5 f$ N1 Y<P>{ </P>+ ^/ F( Z2 l+ a9 {8 g; i
<P>ListView1- &gt;Items- &gt;Item[m]= </P>* ?2 x$ \2 }1 u
<P>ListView1- &gt;Items- &gt;Item; </P>
: d% I$ m# k3 M6 p! M% o: q( T<P>ListView1- &gt;Items- &gt;Item= </P>
: T+ m' X, x3 n9 ~<P>ListView1- &gt;Items- &gt;Item[j]; </P>' {/ |2 I  u4 p4 }0 ]4 P
<P>ListView1- &gt;Items- &gt;Item[j]= </P># b* e* o& Q. A8 k  \7 {6 ~5 Y/ V; E
<P>ListView1- &gt;Items- &gt;Item[m]; </P>% H# a4 Y8 [2 ^
<P>} </P>
& L, \1 W5 y8 O$ W$ E2 D, b<P>} </P>
1 K& F$ F7 p; i; Y- n+ ^. z<P>else </P>/ \; e( x6 [3 ?; J0 P
<P>{ </P>6 F+ k# d1 R0 `" |/ W
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
2 t7 q7 ^6 H( ~1 k<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
; T0 \& D3 |- D$ {0 @<P>{ </P>
' ]+ W- F/ T5 V0 b+ B<P>ListView1- &gt;Items- &gt;Item[m]= </P>
  O& ~8 Y5 P7 [0 `. y<P>ListView1- &gt;Items- &gt;Item; </P>
* A. ~0 f# `! I3 `+ F. z! h<P>ListView1- &gt;Items- &gt;Item= </P>* `! ], w$ D0 `5 R0 ^( B3 t: k
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
' c, p+ ?4 G2 ?4 l6 x<P>ListView1- &gt;Items- &gt;Item[j]= </P>
5 W" V& p2 i. m6 C( q<P>ListView1- &gt;Items- &gt;Item[m]; </P>
8 J/ P  }! Z& n  C3 K. ]* p  ^# D0 H! H<P>} </P>
, ]3 g& @5 r5 h/ X<P>} </P>
5 y. B, z& ~, }4 G<P>ListView1- &gt;Items- &gt;Delete(m); </P>
7 L0 z$ j. X3 A1 N( m0 K<P>return; </P>
8 R, a! D+ W- F! _8 l5 f% R- P<P>} </P>4 o8 P- ?. M2 e+ U2 b7 H4 ^
<P>  </P>$ u# }" L# W4 a5 V( |
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>- ^6 V9 F) A5 ^4 K7 L3 J5 v+ V9 a8 h
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>9 P7 Z: s* K3 R$ @! m7 y
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>8 z7 c8 g5 ]" V2 A* H5 Z
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>5 b6 l' n! C; ]; S3 Z; o1 V* o/ C
<P>ListView1ColumnClick前面即可。 </P>  Z2 ~* f. C9 O, v5 [/ U% F
<P>#include &lt; vcl/dstring.h &gt; </P>
0 \* u9 t% G( S# b- X. l<P>AnsiString __stdcall sg(AnsiString str,int n) </P>$ h! |( T3 T! K: i
<P>{ </P>
0 Z+ t7 Z3 n; `9 j; F! |<P>int l,i; </P>
- W$ {+ E0 O6 B7 \0 A$ g( Y1 e<P>AnsiString qq(str); </P>% j1 i* h' d( S& J  b8 w  n
<P>l=qq.Length(); </P>
. z, D  u: r: T: C. O( Z5 [7 u<P>AnsiString p(str); </P>2 Z, r$ s) _. @3 Y! g6 X+ x2 x, _! {
<P>char a[]="\r\n"; </P>
7 d: y; T: d/ F( g<P>int j=0,k=0; </P>4 f. x  }' [% y' q9 E3 O
<P>for(j=1;j&lt; l;j++) </P>! l% A* m' j( I
<P>{ </P>0 k% I1 V- X0 F+ X- ^; x& B
<P>i=1; </P>
" l% k: h& {0 I, f! ^! C6 I, D3 I<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
$ G8 G, Z( B& P! L( {<P>{ </P>- X  W2 b# F0 s/ R
<P>p[i++]=qq[j]; </P>
$ f) X5 [3 E2 ~0 q2 q" B! }! z4 l<P>j++; </P>
! C  k  }: x% r$ V# @* x<P>} </P>; }" g9 }/ q# Y1 w5 @! D2 j
<P>k++; </P>/ z- v2 U# F6 A
<P>if((k-1)==n) </P>
4 \" S$ B7 c3 I5 b. h+ J% c<P>break; </P>
  v# J% x% h) b. d% n1 D5 g- l<P>} </P>- x& E# U4 y; m. l
<P>p=NULL; </P>. }! |8 r4 c2 x' G5 Q9 X, I
<P>return (p); </P>
; H0 ]1 M1 r: M8 b<P>} </P>; s! k: j  j+ B' G5 y/ B
<P>  </P>
4 h) |4 V9 S, T  I0 ?7 P4 ?% Q<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>$ _+ U8 ^! T6 c# a9 ~- k" H
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
8 h7 ~; T0 Y' B& @0 o<P>可完成对此项目的点击排序功能。 </P>7 }8 J' q3 l! Q5 X, _' J6 k
<P>for(i=0;i&lt; m-1;i++) </P>
! f( k. X: O1 \( P<P>for(j=i+1;j&lt; m;j++) </P>
; F$ n/ a( U, V<P>if(od) </P>  k+ k0 M4 ~2 [8 h, N
<P>{ </P>1 {; n, e, {" s1 X! g
<P>if(sg(ListView1- &gt;Items- &gt; </P>
5 g; i  C2 Y4 i' q8 C<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
7 ^  I; O& P/ ]# L3 g<P>sg(ListView1- &gt;Items- &gt; </P>) A9 ^/ m# h5 e/ U) p/ S
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>* o/ e' B  N7 _

% L+ r; G4 [; B( `' @; d<P>// ...以下从略 </P>
/ d* N$ q2 s$ X  q' l) V6 P) o<P>  </P>. w$ S: v1 \/ m# t% E
<P>最后,删除临时的交换项目。 </P>! R8 q0 A3 U, t1 r2 X
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
( H. w* x6 `, C: N" t" A( u/ r<P>  </P>
3 H7 l/ ~8 n" p& s<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>" ?& L; H9 _$ T1 ~, u
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>% J; A. T: [5 ^. W" i
<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 02:51 , Processed in 0.373281 second(s), 52 queries .

回顶部