QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>0 y0 ^0 g  A9 v! }. p
<>  </P>
* a) q- @; u" P# B; z+ E" G7 A<>天津大学电子与信息工程学院 </P>
3 Q7 Y6 K$ G% G3 O- B& H1 S<>宋天宁 </P>
: @$ \8 ?1 I( @# W$ W1 b1 n<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
$ ]5 z6 Z/ i: a6 h<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>+ t1 M) u. a  Y4 o
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
$ g7 i4 w5 J) A" a' }* L<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
' L4 H' G3 v4 Y  ^' o: i<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>: `; \2 f0 w" g: \- ^
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>6 i5 O  n/ c8 e, O- s# Q, @
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>: a* @  B" w, ~5 L5 y+ u3 N
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>+ _5 F( t, B) K! x6 D. }
<>写自己的代码以完成这一功能。 </P>9 m. ]8 ~* t  Y9 H0 G
<>  </P>8 N* O4 p" y8 L
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
7 o  L. k1 M/ a* Z' @1 t<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
* w  ^1 J  ~& l<>内容以升序排列。 </P>
4 S# x. ~3 c, a3 i0 F- W<>  </P>; g0 j/ |2 ]. W
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>+ ^& X1 V& w- \+ a
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
4 i/ v1 W9 {' h, Z6 W3 g/ H<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
, P! S( _* H7 u6 U/ [) a2 M- D<>包含子列和主列上的内容)。 </P>- I% o* U% I# m5 C- o2 p
<>  </P>
' R6 A0 r; M  A7 s) k9 ^<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
7 _% ~% A+ r9 K, P- m<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>! S; ?- m6 K  \/ L: w+ \8 q$ R
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>8 T1 p; T! j6 J8 w4 o  w$ [
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>" B5 r8 c' N( b0 j5 Y. y
<>  </P>
5 A: ~8 b* X. f. q  c  q<>  </P>  H3 R. l, z3 j
<>void __fastcall TForm1:istView1ColumnClick </P>
* p- X' t$ z( w7 C6 k0 W<P>(TObject *Sender, </P>
0 L: I; \4 y- K8 q* D<P>TListColumn *Column) </P>
7 L5 B8 n, ]' f& ^<P>  </P>; h$ y+ _  _+ ~- d2 k
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
: ]( t* `4 C0 G. d6 t, v& v<P>点击的列的信息。 </P>$ l6 |* o3 i9 E9 K
<P>---- 下面先定义变量: </P>& e2 f# [) N% z/ P& o+ y
<P>  </P>
  K# t/ t) d, m" R, C. J4 C5 ]/ `<P>int i,m,n,j; </P>/ F! A9 T. |1 }0 u6 R
<P>static bool od=true; </P>
8 X# }. i0 N8 Q1 l" }$ H  p<P>od=!od; </P>
) E" y3 ~% M$ A1 P<P>  </P>
1 t% `$ c$ [; q* n. x<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>1 J  O6 U: U' T+ w3 E0 r
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
" o- S5 R) C; Z0 z<P>列表框中的总项目数。 </P>
# D8 N7 M- o  X$ q: N7 C- `1 o<P>n=Column- &gt;Index; </P>9 h" V( ?8 _4 a; `4 e
<P>m=ListView1- &gt;Items- &gt;Count; </P>
- s" }! f; N- R3 L' U<P>  </P>
* z: w/ u5 q- P/ \+ k: x1 i0 n9 {8 j<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
2 K0 p! F: ~3 @6 U<P>ListView1- &gt;Items- &gt;Add(); </P>
8 O3 p. [- U, H9 t1 B) s; Y<P>  </P>) g. q9 Q" ^" ^& G
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
: U, x; T+ H. q<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>4 C$ B1 k( O) T
<P>if (n==0) </P>- H* I( p/ @; S4 t( p: c$ y
<P>{ </P>$ o! z  |$ W( Q3 g4 {
<P>for(i=0;i&lt; m-1;i++) </P>
9 W7 w! l! k0 O& W) g. o" v  r<P>for(j=i+1;j&lt; m;j++) </P>
& f! T/ n  i2 `: v% N+ V8 {9 R<P>if(od) </P>  U( j; k; C% n; Z4 o- G
<P>{ </P>
3 o- ~5 K/ ]" L  e" n<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>+ a; n, z" v# w, B& O
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
' M! j$ [: F- ^" l2 K# F<P>{ </P>
+ [5 |4 ~# w& {& T" W<P>ListView1- &gt;Items- &gt;Item[m]= </P>% a! ^8 `. B, H* i
<P>ListView1- &gt;Items- &gt;Item; </P>; W* S3 l- J! h3 O
<P>ListView1- &gt;Items- &gt;Item= </P>+ Q. F8 I( d* b5 k4 _0 p7 A
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
# H5 l( i' N3 V/ X2 w# l2 Z/ w8 [<P>ListView1- &gt;Items- &gt;Item[j]= </P>
7 G2 P  O. O; c( M8 u9 L<P>ListView1- &gt;Items- &gt;Item[m]; </P>; M* Z( o7 p0 {  j/ p% ~. _0 o
<P>} </P>8 x" @9 X- G. b& i. Q
<P>} </P>
! q/ a) V- y" g. S' @5 k<P>else </P>
5 B  s3 f" `; A: f6 c3 U% |6 C) n% O<P>{ </P>
4 @$ t3 }4 ?+ O8 g5 L( Y4 e. E<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
, d2 p" k0 d4 b8 d<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>( [, l. m, r: {' z& ]5 G1 u7 u
<P>{ </P>
0 C# K7 j0 e" X# g<P>ListView1- &gt;Items- &gt;Item[m]= </P>
& N& |) O' D6 [# x2 {& C3 c<P>ListView1- &gt;Items- &gt;Item; </P>7 I& V. X2 a7 z4 R3 q$ l; J( X
<P>ListView1- &gt;Items- &gt;Item= </P>
" [) d& O  K9 r0 l. d6 N: m<P>ListView1- &gt;Items- &gt;Item[j]; </P>
  M  o/ Y+ l0 ]: Q- v5 j" ]( e<P>ListView1- &gt;Items- &gt;Item[j]= </P>8 |5 `) e0 L& F7 ]9 K
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
" s; l% ]% W! Q0 T0 b4 o4 j3 {<P>} </P>
- q$ y3 `) U0 K<P>} </P>% O: }: @( S8 `+ X6 A& ?" D
<P>ListView1- &gt;Items- &gt;Delete(m); </P>( h( \4 c& |1 y; g3 N+ O/ m
<P>return; </P>9 p; {% M! ?3 ]) g  s$ x+ x% l
<P>} </P>$ b9 R2 t0 \4 P8 d; M6 ]5 S
<P>  </P>3 T( T5 g' y2 R) C  J8 j
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P># m) W" v5 y8 O. |- Z( m
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>4 P4 p6 j0 b2 I/ W5 g# m
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>; O  J# U7 @) m! l
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>+ _/ f9 K- A. `4 e
<P>ListView1ColumnClick前面即可。 </P>7 L! j* E: W: V1 D! T) p
<P>#include &lt; vcl/dstring.h &gt; </P>" M+ }! h/ ~' D4 ]9 M
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
7 ?& }) q, b$ V) V: g+ `' i<P>{ </P>; ?& A3 e5 F0 v0 q! y0 B% p
<P>int l,i; </P>% L- O& C. P3 f( r( K. n* [% p
<P>AnsiString qq(str); </P>
- J$ P% x, t4 {6 `<P>l=qq.Length(); </P>
* L' g+ ]) c, y1 C% F<P>AnsiString p(str); </P>
4 {: q3 Y( j6 p& z. V" D+ b- C, d<P>char a[]="\r\n"; </P>3 F& S+ y  ^2 A
<P>int j=0,k=0; </P>
, h0 n, o  U: i, }<P>for(j=1;j&lt; l;j++) </P>
( D! ~) X  s5 `6 n<P>{ </P>7 {  O2 Y; F" B' O  |% i4 H/ r
<P>i=1; </P>+ J- C" z" M/ L1 H9 Z! E- U
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
7 h+ ?2 F/ m9 K! X<P>{ </P>* M4 Q2 d4 f1 w* q, E4 @7 ]
<P>p[i++]=qq[j]; </P>- ?6 ^- e) e( K; V3 K
<P>j++; </P>) r, u8 {+ z7 W* N8 S
<P>} </P>6 `' J# l1 l  o- J! _" E
<P>k++; </P>
6 Y( @' ]! ~+ k: Q! B: g<P>if((k-1)==n) </P>
' g7 B; T3 M  p+ g/ t6 I, G$ B" b<P>break; </P>
. g8 `( ?2 V% l) y6 Z8 c' d<P>} </P>: E7 ~' z6 ^3 Z2 y1 I
<P>p=NULL; </P>
- Z) t- I4 ~/ G<P>return (p); </P>
* }& {/ d" c9 f% l! X2 `; P<P>} </P>* K& _1 O' g6 D" o$ |6 u
<P>  </P>
" E- k  q6 L- @# Z) m$ t& C( W# j<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>' t  E( r- v4 q. m: J
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
! d' [9 x1 M# U8 a2 K& B4 ?5 U) ^<P>可完成对此项目的点击排序功能。 </P>9 Z7 r! }1 o! n
<P>for(i=0;i&lt; m-1;i++) </P>: d4 m3 W2 a6 j' ?
<P>for(j=i+1;j&lt; m;j++) </P>
, Z1 o) H7 Q  o7 z1 }<P>if(od) </P>/ e; ~4 T0 Q+ b7 x) O: t% H) T$ v
<P>{ </P>1 C) o& V( M6 ?: e
<P>if(sg(ListView1- &gt;Items- &gt; </P>
: Y6 |1 |3 S2 B$ R4 W1 W<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
# ^  `% P0 n1 ?( b) f<P>sg(ListView1- &gt;Items- &gt; </P>
# I& r7 @8 l! ~. h( G7 j<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
, q, g* T: q  r% z
' @+ A3 b$ Q2 U<P>// ...以下从略 </P>
3 G& n2 B" S# D7 p7 T1 M1 n, S<P>  </P>
" V8 F- J" i2 _% c/ G- u8 `<P>最后,删除临时的交换项目。 </P>* W* _6 T8 ~- G
<P>ListView1- &gt;Items- &gt;Delete(m); </P>% h8 R2 e' W" x* F: @. M: G
<P>  </P>" ?5 f* O. ?: x% w. @
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>0 v9 b4 [$ P$ H) A  _6 h& x1 A+ W3 u- x
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
9 \7 O  h7 z% y) a<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-6-30 05:36 , Processed in 0.375670 second(s), 51 queries .

回顶部