QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
, j) {( P! E. A  Y4 C/ F! d; O<>  </P>! L, W3 Q! z3 x  ?  Z; z4 i. S
<>天津大学电子与信息工程学院 </P>! V8 M  k  c$ y5 \# t/ ~
<>宋天宁 </P>
! y: y6 h, n1 `9 ]6 C<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>$ ?( q7 i0 w, w5 o% K8 \: R
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
6 M) E7 `: k* Y$ z( A4 v; R<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
" g% L( X- k/ \( Z<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>7 B) @5 y- h- U
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>& z7 C5 t+ Z* Y$ Z6 @' R) x
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
# Q6 u% U" M* @+ T4 O- I<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
8 P1 S# {* g% {4 b3 u+ f+ @5 a<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>; f) S+ h3 u; l4 a0 O# }$ U4 a
<>写自己的代码以完成这一功能。 </P>6 s" v- A1 [, R4 |7 m6 M# }0 z
<>  </P>% E: C3 ~2 _  g1 A! u% B1 i0 L3 u
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
- m0 s9 P, x! k<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>' v, z/ a1 V0 M- z5 ^
<>内容以升序排列。 </P>( Q5 l2 u4 F- Z
<>  </P>
7 c& C8 I3 S, l8 d) ^<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
2 V+ n2 d  M; P6 w<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>5 P  P/ |' K$ C7 d: F
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>; Z! Z5 r% a' O1 I  w( q0 P! j8 t' J
<>包含子列和主列上的内容)。 </P>
' i  D5 S6 `0 _& Q<>  </P>
$ b9 D! ~9 ^8 V: E% w8 M<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>6 s2 H$ l$ N) h, k& b
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>6 j  Z; A0 T) c4 v- C0 p3 @4 O
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
2 O# S% t5 _/ b* C$ [+ L$ i<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>) Z) I+ t2 K6 m" k, ^6 q7 H8 f$ z2 ~
<>  </P>% \( q, i8 r. K7 f$ z/ l+ z$ Q
<>  </P>
3 j% Q8 x3 ^& ~7 d4 ^4 B+ n<>void __fastcall TForm1:istView1ColumnClick </P>& N( K& ?" H& L
<P>(TObject *Sender, </P>
" p( |) T% ^% P8 x8 G<P>TListColumn *Column) </P>
/ }& \2 L( Z- D  U: h<P>  </P>
% T" t5 K8 T8 F) |/ L<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>1 Q3 {9 b+ h/ ~! n. S% o0 W
<P>点击的列的信息。 </P>* f3 l% \  X! B
<P>---- 下面先定义变量: </P>% h' f( T" [/ Q% K9 g/ Q
<P>  </P># S- B" R; c  Q, _
<P>int i,m,n,j; </P>& u8 F# ^: x0 B) M( d
<P>static bool od=true; </P>0 s1 ~8 F2 l  S6 l' \  U( o
<P>od=!od; </P>4 I& Q+ d8 g: q
<P>  </P>" L) d4 H& ?! ]0 x4 N1 r' c
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
3 ]3 H' b0 y% T- Z' g<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
; x0 y5 j, C/ N5 }5 `. D# i6 e<P>列表框中的总项目数。 </P>) w5 r! j- }' r( W6 Z- W, s: \
<P>n=Column- &gt;Index; </P>" A3 l% @. o2 N' O7 Z' S
<P>m=ListView1- &gt;Items- &gt;Count; </P>
4 J0 l  c5 d& h% L& }& G7 h8 g<P>  </P>) i8 i  a7 @& l/ X8 \$ }
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>, u1 Z. G2 _  m  s7 V- W, Q
<P>ListView1- &gt;Items- &gt;Add(); </P>0 q2 [% f+ i) n
<P>  </P>$ X& t, S& N( F4 r1 |- L
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>" p4 n/ [1 C: E6 ?) ], r
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>$ j$ n8 {: ]7 L6 f$ v6 \$ |
<P>if (n==0) </P>+ i( n- A, h( Q( p/ A  A% C
<P>{ </P>1 d. ~' \1 F% s! S/ m
<P>for(i=0;i&lt; m-1;i++) </P>3 e& D# W* j+ ?# @- @9 g- p
<P>for(j=i+1;j&lt; m;j++) </P>& ~/ R  H% }5 d, c5 W* N. q2 S
<P>if(od) </P>, n: l5 l6 ]: M. p( l  D; U, o
<P>{ </P>- F- @5 o) R1 F1 @  F
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
# |2 h- E8 }" v# b) `<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>, ?) m1 }/ b4 z) j; E+ N! E
<P>{ </P>
7 o8 w$ D& k) A% H7 Q4 H3 l# o7 [<P>ListView1- &gt;Items- &gt;Item[m]= </P>
+ V5 j0 O: i% b; h<P>ListView1- &gt;Items- &gt;Item; </P>
- W& j1 S1 Q8 T/ D<P>ListView1- &gt;Items- &gt;Item= </P>1 ^% ^' P+ Q; h4 D
<P>ListView1- &gt;Items- &gt;Item[j]; </P>; A0 B! a) c* _/ M
<P>ListView1- &gt;Items- &gt;Item[j]= </P>6 J* ]0 V. A) I; t+ J' P
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
& }6 K8 M2 N" c<P>} </P>4 a& \$ s& M: b; K' J( Y
<P>} </P>+ i  \: O+ p5 R# H  M
<P>else </P>
/ S$ x; a; a- V- h/ q<P>{ </P>: z  w, g; x4 |! E3 u+ v
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>7 q2 h8 c9 c/ T, k) Z: k
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
7 b0 F* k% X# Z+ o# E  V3 D+ d<P>{ </P>0 x: R2 y* @3 X& A6 m
<P>ListView1- &gt;Items- &gt;Item[m]= </P>9 O" X$ m+ d. x
<P>ListView1- &gt;Items- &gt;Item; </P>
2 F* x2 h3 V8 g8 j, E. q) A<P>ListView1- &gt;Items- &gt;Item= </P>
2 }; z. D# d: D, g<P>ListView1- &gt;Items- &gt;Item[j]; </P>/ B/ H% o' [  y* ]( ^9 R; P% T  r
<P>ListView1- &gt;Items- &gt;Item[j]= </P>) }, V3 D* {, C, ~
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
/ H  b& T- t0 U<P>} </P>
. H8 L. D& f6 i<P>} </P>" P4 Z" m# f. ~; |! c; l1 Z% I$ @
<P>ListView1- &gt;Items- &gt;Delete(m); </P>! o. i4 O. p2 Q7 i3 ~7 v! M6 r
<P>return; </P>
; ]! z) E$ E" @# M3 b: o# Z! k- Y<P>} </P>
; }4 f( D0 N, d! M+ s! _<P>  </P>
9 K8 U; Z" X; u3 q4 `' [  U  E<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
( Y) [( d& R. |6 z) N: c3 A<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
! F% [, i+ @! K<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
: A, l/ N6 |+ n3 O' l* l- A. [! L' p<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>( l+ A- Y3 t) i' T
<P>ListView1ColumnClick前面即可。 </P>. F: \3 t+ H( S. j
<P>#include &lt; vcl/dstring.h &gt; </P>) s' U4 [2 g# Y$ M
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>0 h. T% t/ l$ b4 z/ f
<P>{ </P># ]$ N& y8 x5 z2 k$ s' j* y6 C
<P>int l,i; </P>/ F. y& N, D; z
<P>AnsiString qq(str); </P>
3 C+ j3 C2 y& N. q<P>l=qq.Length(); </P>
3 |4 U) ~4 r6 i<P>AnsiString p(str); </P>2 f0 H8 B' C$ u" W% `
<P>char a[]="\r\n"; </P>5 ]2 g8 z1 H- K% |; |0 ~* \  u
<P>int j=0,k=0; </P>
; j/ b2 a0 j, @9 q<P>for(j=1;j&lt; l;j++) </P>- O9 u% u/ s+ F: J
<P>{ </P>* V: L+ X7 v- p, f
<P>i=1; </P>* ~  @" [" n' X9 ~* h0 M
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>/ M' b+ ^: W( N% w
<P>{ </P>
8 j* G) N, `9 F4 o7 x. b! |<P>p[i++]=qq[j]; </P>2 s* s3 C+ n8 q+ i3 ^8 E! Y' T
<P>j++; </P>. N" o9 ?& r/ i9 K( u  S) U0 M& ^( e
<P>} </P>2 F8 `, a0 w) S' |7 p" a
<P>k++; </P>4 X7 E  l# h/ f6 @) d  ^
<P>if((k-1)==n) </P>9 [3 s1 @, b" C4 `
<P>break; </P>
8 q9 b1 [5 B' O7 d<P>} </P>
# W: ^' M6 k1 O4 V2 U<P>p=NULL; </P>
- N# g. w' W9 W8 h6 p9 |9 D<P>return (p); </P>0 S1 s, v2 P, A( e. t
<P>} </P>' d3 q* s; N6 q1 v7 [
<P>  </P>
, H6 K  e% d$ D' Q6 g+ W0 A<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
7 g8 M* J) U+ \& O) n<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>) V4 }; t. T" Q; c, g/ c
<P>可完成对此项目的点击排序功能。 </P>
  Y' w- Z" F% F. }7 |+ Q, Y<P>for(i=0;i&lt; m-1;i++) </P>" Q0 [! |3 O7 G' K
<P>for(j=i+1;j&lt; m;j++) </P>
9 e& }, s, d. y2 l' z4 s<P>if(od) </P>0 H4 V% x- }  y
<P>{ </P>
) G% g; G! ~3 K/ [7 U8 n$ ~<P>if(sg(ListView1- &gt;Items- &gt; </P>
' N; ?% v, v/ v, [% }<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
8 N7 L; b1 y+ ?<P>sg(ListView1- &gt;Items- &gt; </P>
% Q; h1 [- A7 ^0 J; a0 ?<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
1 K% f- ^% Q! _! _9 d6 m
5 T: v) _$ N; H; P, `) N<P>// ...以下从略 </P>
: f& C' s8 c6 m# c5 k9 V: m<P>  </P>
- s6 y, _& I. S<P>最后,删除临时的交换项目。 </P>
- d; u+ y. \- p9 A4 l3 D4 z<P>ListView1- &gt;Items- &gt;Delete(m); </P>: a, ^) }5 r$ g* \1 @6 N
<P>  </P>9 q$ w4 N$ D' I/ W; x
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>' t% X& q9 e, t6 i
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
; g# @+ G3 k+ n<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-11 12:06 , Processed in 0.466842 second(s), 54 queries .

回顶部