QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>1 u) W4 n  ~$ X. W6 }- `4 n
<>  </P>% K- ^4 I  h' E$ j% Z: z0 e  |
<>天津大学电子与信息工程学院 </P>" Y% r- a8 l5 F& h* ?8 A  F
<>宋天宁 </P>
- l7 \6 O$ T& w! C0 C/ K<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
1 o% K0 o% w% ~+ q' ~  J2 q6 j<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>. j2 b9 m2 d# S' w
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>( n2 d" c* u6 Z( F  G
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
, P% S( U, H: z. j7 a0 j<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>$ I# ]9 w% S  w+ E0 y& o* Q. r4 p
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
+ H( D, q6 O" j% s<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
1 u  X3 E2 m0 a<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>! j1 I- u9 F2 r% {) F6 v( _4 Y
<>写自己的代码以完成这一功能。 </P>: P0 C- b* W" Y; {& K0 F* w6 }
<>  </P>
* w8 c( J! V' I$ g/ d6 k! F<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>0 K) R* b* `& e. @% h3 v
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>, N+ P* w; e( a
<>内容以升序排列。 </P>
3 t8 v" r5 a$ b<>  </P>' j4 l% `% W# H0 q1 Z& ^/ }
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
+ `' H, u( R" ~1 r; B( D1 l<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
- q7 c, n7 n" [) q. z$ t, Z<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
5 Z4 n, ~/ h5 B- Z) e; U/ s) Q<>包含子列和主列上的内容)。 </P>
: d; F# Q9 _, v! W. N2 @" p<>  </P>1 y5 l' ?7 a; Q3 x
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
' \  c0 [, c7 h( E. }<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
/ k' c7 F  ~' u& O& f& L" ]! v<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>) k2 K) r# J6 x2 R
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
1 b4 ~& D, ^9 {<>  </P>
$ ?! _7 z$ M. E- h8 P; F$ ~<>  </P>8 H2 g: l0 |' g& T
<>void __fastcall TForm1:istView1ColumnClick </P>
. T! H' B/ K; S; K9 t<P>(TObject *Sender, </P>
% _5 ]+ a9 Z) K& h<P>TListColumn *Column) </P>" o* y' Q1 k8 t% v* D- E$ Z" M0 D
<P>  </P>- U( j3 H& x3 j4 B5 Z1 M1 g4 ]
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>$ f, m) K+ J6 J3 ?$ a
<P>点击的列的信息。 </P>1 E# @, d# k0 r8 o9 ]9 Z/ K
<P>---- 下面先定义变量: </P>- C# k1 {: Q; X% }" W/ s
<P>  </P>" d% t' E( D. h1 Z: l: `
<P>int i,m,n,j; </P>
# r! G4 I. A: z  J9 t0 O, w: B. l! G<P>static bool od=true; </P>
8 v" X! R3 E# Z2 N; f<P>od=!od; </P>+ M* I& e+ _) k/ n3 R7 M
<P>  </P>+ y! ]! o+ t6 t. _; \8 G2 g
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>2 S: X, `5 b  w1 j$ O. g) [
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
1 r( t! c  J" R1 ]' p' w. W<P>列表框中的总项目数。 </P>
$ ~7 z$ z  R7 a: v<P>n=Column- &gt;Index; </P>5 M" L4 }$ `+ Q" x1 K! [
<P>m=ListView1- &gt;Items- &gt;Count; </P>
+ B/ O$ _; o* \" C2 `<P>  </P>
3 \# I# A- A7 `" E; @. }. A" H<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>! w3 B: j% \: L  C
<P>ListView1- &gt;Items- &gt;Add(); </P>
8 Y. O& _: r* T<P>  </P>
3 `1 x9 S# G9 V1 |1 @<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
1 |5 @# K; h* L+ {% X9 K<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
2 ]7 O3 K8 _. Z  e<P>if (n==0) </P>  p  i5 o- f" R% a4 F, \- J
<P>{ </P>; X& ~% g1 q* T/ k& T. I
<P>for(i=0;i&lt; m-1;i++) </P>$ S' _9 G# `/ ^/ }2 P
<P>for(j=i+1;j&lt; m;j++) </P>! i0 q: Y# w' t. \( S0 ?  r
<P>if(od) </P>, _5 t0 K/ p) E; M5 ]- s
<P>{ </P>
, A4 t% I' J5 Y<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>- B# A7 k8 j# _: Q0 {0 B+ `
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
/ G0 P  |+ ]- ]5 S<P>{ </P>9 a8 G! V/ |: [0 i6 [$ J- }  F
<P>ListView1- &gt;Items- &gt;Item[m]= </P>9 u& y9 [; T2 J" E9 T2 o0 i9 ]
<P>ListView1- &gt;Items- &gt;Item; </P>- u6 U2 ]& @( v- ^; I+ m
<P>ListView1- &gt;Items- &gt;Item= </P>
; F8 O6 |4 ~# B; H& ]<P>ListView1- &gt;Items- &gt;Item[j]; </P>1 `8 k& {6 ?" Q/ m/ j7 |
<P>ListView1- &gt;Items- &gt;Item[j]= </P>) }( J% S4 N1 X6 K$ w
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
" x# V, X) C/ @( @4 }<P>} </P>
8 Q; c" A* ?9 C( @4 z, y<P>} </P>
. k7 W5 H) s* e<P>else </P>
% `% P# c$ M& @0 j+ o<P>{ </P>7 G) M2 Z* \( ]0 m2 \! N
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
* r7 P& S  d. [<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
  L$ J: S8 b( I  [% ~<P>{ </P>7 b5 i" d' s" ]5 _) l
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
9 M# \+ T% E$ z5 `8 p7 \<P>ListView1- &gt;Items- &gt;Item; </P>
- n" j$ n$ W5 J. n% G7 E5 y<P>ListView1- &gt;Items- &gt;Item= </P>
" Q) G/ N: e& s, B0 ~<P>ListView1- &gt;Items- &gt;Item[j]; </P>
, _* N( J! \/ p<P>ListView1- &gt;Items- &gt;Item[j]= </P>
1 U0 K6 I4 |! _4 B; C; S! {<P>ListView1- &gt;Items- &gt;Item[m]; </P>! |, q# i1 f  Y3 l: c
<P>} </P>
" x3 }" x8 Z# z/ O! j<P>} </P>
4 Q8 R7 Z& H- ]% u  O<P>ListView1- &gt;Items- &gt;Delete(m); </P>
# h$ a% e  S5 F<P>return; </P>/ i/ l7 T2 |. K, ^* O. R( r
<P>} </P>5 j1 i6 t8 L  {$ N
<P>  </P>" K1 {( }( O) ?4 c! d( G- h
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
, I7 d6 M8 Q. `9 z4 |' Y! ^<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
; ?' s( n; m3 x2 w7 I<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P># d  ]: @" y' s8 t
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>4 A: f3 _6 L2 m/ n& K+ @: ?9 Y
<P>ListView1ColumnClick前面即可。 </P>2 G- w  s4 ]( V
<P>#include &lt; vcl/dstring.h &gt; </P>
1 v6 L8 e, Q" U, e) S2 I( @<P>AnsiString __stdcall sg(AnsiString str,int n) </P>* ]" B2 R6 X7 D6 J
<P>{ </P>' l' O; I0 G/ E/ V/ g
<P>int l,i; </P>
& a. f% d! q5 N$ l6 C<P>AnsiString qq(str); </P>
$ n( ?5 W% s  H$ a+ i% e<P>l=qq.Length(); </P>
: ]# z- n7 h/ }$ @8 s" Y<P>AnsiString p(str); </P>
0 \& v, |8 ]/ m& F5 k1 Y<P>char a[]="\r\n"; </P>
* g' t. |. h7 U( a' R, i<P>int j=0,k=0; </P>
( c" }% W, v* Y& j<P>for(j=1;j&lt; l;j++) </P>
8 O  m" C0 q2 g' w8 {" z0 |, S$ j# z<P>{ </P>, _& T  B" u& O3 [
<P>i=1; </P>
3 [* ^0 u& S! c; R+ c6 m<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
+ l% C5 t7 t1 N- C4 C<P>{ </P>
! ?! r  Q5 }4 r" G  [; b/ d<P>p[i++]=qq[j]; </P>8 M- ?& D0 A: q9 p' l8 n
<P>j++; </P>
3 V- }+ b% U$ h+ ?& h2 v<P>} </P>
" s/ h3 g& b  r* k1 @% @! d<P>k++; </P>- L4 v2 H* N: _7 F5 y" G
<P>if((k-1)==n) </P>
' ?' [5 c) F' d7 N) q7 O6 ~& L<P>break; </P>0 n- }: K+ F# }8 C. ^$ w
<P>} </P>! j% x$ @) r7 r( i; p
<P>p=NULL; </P>2 x& x( ]8 ~; x5 _* p; Q
<P>return (p); </P>
- _3 v/ p" T. f! V" B  D: K<P>} </P>
* Q% P" d/ {  N8 ]' i& ^$ _<P>  </P>7 A& |( |4 s( I! O2 `
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>% R% H0 C. H! k1 V# K6 @
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
* j! B5 D. h; _$ Q/ c3 U<P>可完成对此项目的点击排序功能。 </P>, J* i5 j. v1 }/ d4 B$ D9 |( G
<P>for(i=0;i&lt; m-1;i++) </P>
2 \5 x; G6 G& S2 Z<P>for(j=i+1;j&lt; m;j++) </P>. {# J# o! l' S+ F
<P>if(od) </P>% [2 ~5 u9 k! C
<P>{ </P>
" l9 L* }) f+ Q. N% t. k" c5 {<P>if(sg(ListView1- &gt;Items- &gt; </P>
& [* u  ?. m8 H, C: E9 a- p2 ~8 v4 b<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
9 h1 m+ V7 C5 ?+ W: O<P>sg(ListView1- &gt;Items- &gt; </P>
) r/ m, D. l4 N<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
$ A: x+ d' r: v3 Z# W% \# R0 ~7 R7 v' j9 j9 F; M8 ]2 t
<P>// ...以下从略 </P>! w+ g6 A# n' b* Y8 U
<P>  </P>
3 p' _3 l! D$ M* m, E0 E# ]* Z9 T<P>最后,删除临时的交换项目。 </P>
$ M' D/ h# |0 ^: `1 z3 m9 w7 t<P>ListView1- &gt;Items- &gt;Delete(m); </P>
$ P: y+ o0 M. N& K/ h- \<P>  </P>
  h: `- H6 k& D5 Z2 l. |1 V<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>4 m/ {7 r5 s  D$ B$ b  A
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
) X2 ^; |" N# k<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-9-1 12:09 , Processed in 0.440688 second(s), 52 queries .

回顶部