QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>8 o- R1 S! w1 B  d- i; t
<>  </P>2 s( m, k2 E' G9 k4 @( K
<>天津大学电子与信息工程学院 </P>
% X/ S% @# S+ i- q3 u% E# h<>宋天宁 </P>3 e3 s, F5 R0 a& E
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>" U$ f$ X' K5 |4 ]* W5 B
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>  R5 q7 d+ n3 E% T% J7 L& ~
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>3 d. A. L* M/ T1 Y' y, H
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
5 E9 ~1 e4 Q$ f<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
! Z) @5 Y7 r/ A4 D# \<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
2 U5 t% V( I! ?" L. T+ }<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>6 @$ v) R" R! `: s
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
) D8 B, D& H1 v1 u<>写自己的代码以完成这一功能。 </P>
4 n3 i* C: [  ?7 M0 t7 t<>  </P># r& c. y, D6 c0 k* {
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>% {7 W: L8 f. U+ I1 I- `6 A6 K
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
0 L) @& J2 t; o# |9 B<>内容以升序排列。 </P>  R6 v1 K. I2 c( |5 ^7 _  E8 v" W/ ?
<>  </P>
/ a( D" H- v* w% r0 R) `<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
: m) Z7 U, Z/ V- h& K/ D! {<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>& i0 d+ \" f: I/ z8 |
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
4 M8 r, N& r# K5 A5 Y& [) }$ c: p<>包含子列和主列上的内容)。 </P>
/ H  t0 Z7 l) J! V% B4 O, g<>  </P>! t5 q+ ^. W3 B
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
4 n# h8 ?3 r4 w<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
1 x  L, e* y- h' X/ [4 ?4 ?# ^2 |<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
. z' ?% O7 A9 J9 g; N! v; d<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>' y* \& t& o% d# P% c" o; U6 l8 J
<>  </P>3 m% F0 i' p/ V4 o2 q% w+ W3 q* c) V
<>  </P>
7 n: z6 T- ~, ]4 B<>void __fastcall TForm1:istView1ColumnClick </P>
( \8 k3 B3 v# n<P>(TObject *Sender, </P>
/ b: g% _; h" d' F<P>TListColumn *Column) </P>
8 H+ C' k( z: v9 f<P>  </P>
9 A/ o' q- t8 S<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>; z- N: T9 R% S3 q" R$ c* v! I  E: D
<P>点击的列的信息。 </P>
" A  w& b: a9 G/ b<P>---- 下面先定义变量: </P>
  q" p! ^; ]( l4 r5 g5 p<P>  </P>
! h* g" R  Q) q9 [<P>int i,m,n,j; </P>
# p8 K( y. J' Q<P>static bool od=true; </P>* U% f2 c* W: i( X$ f
<P>od=!od; </P>
8 W- R# g1 u$ y" V<P>  </P>! S8 }8 R1 L6 R2 {1 h
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
  m1 @- A9 p4 |& P1 g<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
8 V' a( N( N# v6 `' P9 z! n1 ^<P>列表框中的总项目数。 </P>
  a7 b& O6 F+ t+ @<P>n=Column- &gt;Index; </P>& z' D' X  d: M2 O0 q
<P>m=ListView1- &gt;Items- &gt;Count; </P>) ]1 \! q" S2 u! `
<P>  </P>3 i6 }, _( Y' L7 _! J* v
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
7 \7 B* d8 n3 `+ K<P>ListView1- &gt;Items- &gt;Add(); </P>
; Y& _4 r) E. G# K4 w<P>  </P>1 E% c) N' M; n4 J5 ?6 D- {0 a& Z
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>( e2 V. V5 c8 Q: S( o. Z" }
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>+ D9 g, K4 I3 s0 g+ }7 o
<P>if (n==0) </P>) ^) F* d/ K3 u6 D" M' H
<P>{ </P>
' W2 [1 h; s; W9 Z' t$ |5 B* P<P>for(i=0;i&lt; m-1;i++) </P>) V/ B& c+ ]$ t; ~
<P>for(j=i+1;j&lt; m;j++) </P>" |0 o0 S7 G7 C9 @) E
<P>if(od) </P>; X' s$ T  e% s( M% S5 \5 k
<P>{ </P>
) C4 e; s2 X2 e/ ^<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
# U1 l+ c$ q( o5 K+ v$ Z  `/ Y<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>8 i$ l) r/ M- U3 @( U% Q
<P>{ </P>
! Z. U9 G0 d3 T0 q0 O# B1 j<P>ListView1- &gt;Items- &gt;Item[m]= </P>8 Y8 s! T4 `! z$ p- C
<P>ListView1- &gt;Items- &gt;Item; </P>8 y' J& F7 |" h/ C* }( K
<P>ListView1- &gt;Items- &gt;Item= </P>
$ R. P& N" }8 |3 d, N2 h<P>ListView1- &gt;Items- &gt;Item[j]; </P>
# W$ m: n& q6 C- j! h- n<P>ListView1- &gt;Items- &gt;Item[j]= </P>, M  M! r& \. v! C6 |5 C/ B
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
, L9 ]! ]; }, p( Y# \<P>} </P>
0 \) C7 H+ D; p7 ~1 a<P>} </P>
3 F- V2 a8 F9 k4 e( {<P>else </P>" W2 e1 E2 j+ B7 S, J# H6 M, K
<P>{ </P>
; f# `1 K! R2 {0 s<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
/ Q9 k2 g% X- M( E8 |( W  b<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
) p. V; Q# M( H( T& L6 G<P>{ </P>
: a; R$ O- w, e. U; b<P>ListView1- &gt;Items- &gt;Item[m]= </P>6 i' e% k3 T* `! D
<P>ListView1- &gt;Items- &gt;Item; </P>( l( P% _' U! _+ F% ?$ [
<P>ListView1- &gt;Items- &gt;Item= </P>
) {; A; g; {1 R6 u$ {1 j1 e5 A% i<P>ListView1- &gt;Items- &gt;Item[j]; </P>, k% d3 U3 H3 r! q
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
8 W* s7 [2 n( I, b( {<P>ListView1- &gt;Items- &gt;Item[m]; </P>; L/ o- \: j$ ^9 N; g
<P>} </P>
7 r$ E% ~& s$ L<P>} </P>
" K) o( H( R. b! M<P>ListView1- &gt;Items- &gt;Delete(m); </P>
$ J; C" @' [* ~5 C/ \& w<P>return; </P>6 j$ d3 V! G7 I/ ]! [/ R+ F
<P>} </P>1 L7 l" r( x& M3 a4 h3 R8 T
<P>  </P>0 V. D; o, ~8 h
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>% Z1 [7 a9 s8 {# A7 E8 L( F8 A% q
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
, ]2 H0 L- ^( {  L  J3 r6 ~* M# S<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>: o$ p: l. D! b
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
2 p3 U8 P" @8 n; h5 {, E+ ]<P>ListView1ColumnClick前面即可。 </P>; ~" Y6 W, R7 J& x  L8 ~
<P>#include &lt; vcl/dstring.h &gt; </P>
0 j& l. M3 k% m# n+ `3 ~<P>AnsiString __stdcall sg(AnsiString str,int n) </P>- S1 M# M; r( k- B
<P>{ </P>
/ l% @* J: ~; e<P>int l,i; </P>1 f- p) y1 d6 F" Z
<P>AnsiString qq(str); </P>
' Y  F1 O2 A1 ^2 F* I# i8 ]<P>l=qq.Length(); </P>
7 m7 a* @% C% r6 L1 D% V<P>AnsiString p(str); </P>
) d: R+ J( Q' w1 K7 q8 _9 h/ c<P>char a[]="\r\n"; </P>+ g% g$ w& c" T3 z) Y
<P>int j=0,k=0; </P>: M, y" `) h; G2 Y; l: Z6 N4 h
<P>for(j=1;j&lt; l;j++) </P>; O$ c+ ~" s+ o6 r& B1 J) q" q
<P>{ </P>6 k! d9 k1 R% D
<P>i=1; </P>$ X$ A' O, i% |# h
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P># C- `2 c/ y8 j  D; T. B7 K
<P>{ </P>% v, X" K! s6 Z2 n
<P>p[i++]=qq[j]; </P>
) _' m; Q: s9 p' v, R<P>j++; </P>( X& R! Q5 e/ ~9 r) ?
<P>} </P>
# ?8 C' E  _8 o3 T8 E+ B  ?1 E<P>k++; </P>
2 M0 h2 i" U6 g7 \& v# ]/ {<P>if((k-1)==n) </P>  Z7 D* ^8 e# E, J/ V
<P>break; </P>
, p- u! V- h7 c- R, m' s: F! i<P>} </P>
* E, l, p# ~$ V: {% g<P>p=NULL; </P>0 p. n* ~) @9 H0 X: O
<P>return (p); </P>
, w4 h$ a  C- d! {; P6 y<P>} </P>
$ }; @8 {  j$ t. i% v* k/ F' @<P>  </P>
4 T( v1 ?, `& n  T6 e<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>+ h2 }4 e9 f' S$ N7 M9 [4 n9 ]# a* J$ F6 H
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>/ O( ]! Y. t( D! y( P3 T! V& L
<P>可完成对此项目的点击排序功能。 </P>+ m8 G! w. _/ a$ {! P2 w' i$ [$ `' }
<P>for(i=0;i&lt; m-1;i++) </P>
7 p" ]5 P6 W/ z& x4 L5 s5 {1 H- z<P>for(j=i+1;j&lt; m;j++) </P>/ v& R" h  F6 p
<P>if(od) </P>
, ?. J3 |" M$ P2 P! Q- O% \7 e<P>{ </P>
3 u2 l8 P; `- a6 b, V<P>if(sg(ListView1- &gt;Items- &gt; </P>
( Z' Q+ y% N2 l7 [! j2 E7 [<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>' r) g* v. H$ n( }. U6 i+ e5 Y
<P>sg(ListView1- &gt;Items- &gt; </P>7 V$ Y" V8 {; K/ L
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
  k2 s9 Q- |  x$ ~/ @6 j
; f& n: \( b- ]/ @* `7 ^/ T1 P<P>// ...以下从略 </P>
6 w' p! I  s  ?1 r. L<P>  </P>
/ Q$ E2 m$ |, k* [<P>最后,删除临时的交换项目。 </P>
- Q. Q+ P  p' a. D& q<P>ListView1- &gt;Items- &gt;Delete(m); </P>
+ ~+ R5 k" E! j* P+ |<P>  </P>
7 B! C4 Z' W- ]8 i2 F$ `<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>5 c0 Q7 N/ _0 Z( O6 A) E
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>% Y# D0 K) v1 f4 `
<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-6-15 01:27 , Processed in 0.609148 second(s), 52 queries .

回顶部