QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
2 L! g) W0 @, m: P% R1 Y3 t. d<>  </P>' q$ E# Y& U; V3 u9 N1 g
<>天津大学电子与信息工程学院 </P>
: m$ j: P- h1 q6 ~  N5 U4 s! G2 e<>宋天宁 </P>
* M' H) O8 B: v- Y<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>; t9 L$ ?3 P' @
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
9 G- A; C, d) R# B0 s: w, |: c  {& S4 r<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>. I' D" x/ e0 v
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>+ e, |# }& u% H4 n. n: d
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>4 w7 _2 V9 ]# p2 K
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
% m! A- r9 R0 ~<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>% H# f6 K1 x1 s5 {. t
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>5 l+ v8 T; _' J2 u
<>写自己的代码以完成这一功能。 </P>
4 p% ~( [+ X# S4 B. ]# j<>  </P>1 x" C; W3 @. y) T
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>3 x+ y' c6 I& K# c' v. |& @
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
4 H' M" W' l0 E% U8 j. e- l8 e<>内容以升序排列。 </P>
9 z( d% o$ k' L$ S& \% V, i<>  </P>
* `' x3 f7 w" M; u/ j<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>7 E; X3 A' e  v/ M( }* z
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>9 t, Z$ z$ r- A" }7 `; k
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
0 A! K) A( ^/ E  H- z<>包含子列和主列上的内容)。 </P>
* u# r7 `! {6 z5 q<>  </P>: q( ?# Y( `0 N
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
6 O9 ~, n3 G7 C2 K3 K( v3 y<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>2 u, W; ?/ Z4 `, r0 }$ a# F) {
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
, h# z2 L5 }% z4 [* l! X<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>) a8 h! e4 F- ]2 L# F
<>  </P>
; ~$ J4 E) G/ ]9 a0 O<>  </P>! P! H3 m% V9 u
<>void __fastcall TForm1:istView1ColumnClick </P>4 ]3 ~/ N, }. R0 }4 h
<P>(TObject *Sender, </P>% I- _! c5 n: w$ g0 c3 n" R
<P>TListColumn *Column) </P>  ^# Z3 v/ r9 y8 W2 J/ r) a
<P>  </P>
2 J" e: u5 |/ E2 s<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>2 P' v; e6 Y. D7 ^! t+ {8 M- s
<P>点击的列的信息。 </P>  Y: B! h5 n0 B9 A* }, k
<P>---- 下面先定义变量: </P>
: N% e1 O0 C( @& k' k. o<P>  </P>$ m& e" S% U: H7 g2 o! P
<P>int i,m,n,j; </P>; J, u2 x) y7 `3 K8 ^9 t: z
<P>static bool od=true; </P>
0 v8 i1 R0 E% P# F# I( R. ?9 S<P>od=!od; </P>
. W: Z* j$ q2 N" k$ b8 \/ p<P>  </P>3 H4 O: |% [. n" j: C4 ]
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
. J' C$ `% j5 {<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>6 q! {+ ~, P, ]% {+ o/ w
<P>列表框中的总项目数。 </P>* V1 Q" q* @- E
<P>n=Column- &gt;Index; </P>! _7 W# K1 U1 f$ x: `& G
<P>m=ListView1- &gt;Items- &gt;Count; </P>$ |2 [% Q5 c3 R2 b! W! ^! o
<P>  </P>- n* m( w  ]7 k/ v9 M4 O* b0 G1 x
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
9 U% h& K: `$ p+ N  Z<P>ListView1- &gt;Items- &gt;Add(); </P>
/ t5 C( X* D6 g, T7 r$ P<P>  </P>/ j% }4 Z4 s" \8 M
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
7 |: y7 f8 ]) b: t( o<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
  c# A! ^& h, h<P>if (n==0) </P>
, R% {7 b) w+ }, N, G5 L<P>{ </P>6 a: a$ W) M" x
<P>for(i=0;i&lt; m-1;i++) </P>
$ h9 J( u- k' t! K7 j& `, i9 y$ Z<P>for(j=i+1;j&lt; m;j++) </P>
) m& T: x+ }" b' g<P>if(od) </P>
) _8 J# R* G$ C<P>{ </P>0 A% `; g( s! M5 |$ f* [2 ~
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
/ x: d1 r: M( z<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>9 m  S/ {& D; |
<P>{ </P>
) O9 N$ [5 m% m6 O7 Z" E: S<P>ListView1- &gt;Items- &gt;Item[m]= </P>
" k8 U" L- N% t0 Z, z+ \: G<P>ListView1- &gt;Items- &gt;Item; </P>
& N* O8 u, {  N" M/ D0 t<P>ListView1- &gt;Items- &gt;Item= </P>) z  k5 i/ k0 E/ }4 I: j
<P>ListView1- &gt;Items- &gt;Item[j]; </P>3 b9 G1 C* H" Q2 l& [
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
  e3 w$ H* c& I- f8 t; j* u<P>ListView1- &gt;Items- &gt;Item[m]; </P>" l; X6 Y4 F9 @$ h% i2 j% M# y5 n
<P>} </P>7 O6 B$ |! u- h. e$ P- |& P
<P>} </P>
& h# m+ S* G" C) }: n' j7 i1 N; ^<P>else </P>( v' E6 S# o9 M/ U$ a9 A1 e
<P>{ </P>
1 V, O3 }' S. R: n1 L, c<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
1 I. V( T" l! N. r% g) ~<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>$ t  V+ N9 {' r! }
<P>{ </P>( _+ W3 r0 L2 R4 ^
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
6 Z- e; p# ^5 E* I& g+ {9 @) X<P>ListView1- &gt;Items- &gt;Item; </P>3 u/ k5 J( O6 H+ j$ t" ?. z% m! ~
<P>ListView1- &gt;Items- &gt;Item= </P>! ^3 R% U3 \$ D9 o, r1 V/ R
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
- \3 \, r) F! k6 w7 h1 ?3 E& n<P>ListView1- &gt;Items- &gt;Item[j]= </P>- W/ M" a  R! D5 Y
<P>ListView1- &gt;Items- &gt;Item[m]; </P>4 z$ L* u& R6 w" I3 m& q
<P>} </P>
$ D# M5 I' t+ I; `<P>} </P>0 D) b3 V. h; L$ Q+ ~  ]% Y: M
<P>ListView1- &gt;Items- &gt;Delete(m); </P>& O. Q4 Y+ ^- T8 d4 e4 K# l9 ~
<P>return; </P>' B7 F# }: |) N3 S. }) W
<P>} </P>
7 \! ~4 q: ~" L. ^" Z/ ?7 z; n8 b* y<P>  </P>' C7 `2 h6 U# J  d
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
% _& K$ J6 P4 ~/ f1 H3 N; F<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>$ T1 _6 `6 o) l
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
' h$ u4 f. k. |) b% `# U- Y<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>7 t7 F9 s) H) g& p% n7 ]" d% _
<P>ListView1ColumnClick前面即可。 </P># N$ P  J+ z, e' v
<P>#include &lt; vcl/dstring.h &gt; </P>/ u4 E  S* s* K* w5 F& R6 a
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
6 @& x* `! g$ f: O<P>{ </P>- X7 e9 o) k' B. \. t7 p
<P>int l,i; </P>, C% H7 ^0 u" b3 Z& Y7 I/ p7 w
<P>AnsiString qq(str); </P>
+ X4 p- ]6 H4 P% F8 f* M, Y<P>l=qq.Length(); </P># J( N& U  H+ N+ H
<P>AnsiString p(str); </P>+ c. R. `4 f7 e; s2 w
<P>char a[]="\r\n"; </P>" F* t% v8 G* K! x, V
<P>int j=0,k=0; </P>
9 `+ [' ~+ Y5 \2 `+ M7 W<P>for(j=1;j&lt; l;j++) </P>
$ I9 m4 R$ ^0 z! Q4 X5 j<P>{ </P>
4 G% h3 ?) `3 m/ U<P>i=1; </P>
& R( ?$ f5 i. C) F5 M<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
* M1 @, o: H; ?# P/ ]' n<P>{ </P>
, l% i: l+ `! R0 J: b<P>p[i++]=qq[j]; </P>( r% O4 D9 D, t
<P>j++; </P>/ \! p) N) A0 e  @% L
<P>} </P>' E4 q* R8 Z! `" s( Z/ s, m. ]# H3 R
<P>k++; </P>
5 p/ d0 p, R' b0 A. r% C) y<P>if((k-1)==n) </P>
0 r& e, [# w$ s: M7 O<P>break; </P>6 J2 B' x2 y3 }9 E4 `
<P>} </P>
$ m% `( g: Q* b3 p2 _; g<P>p=NULL; </P>: h  y* x1 T4 P- R
<P>return (p); </P>* \, G1 E; f8 S& ^
<P>} </P>
* G3 C: k( g" S7 _% i<P>  </P>/ U/ H8 q/ v/ W! R. c! t
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
* p: G* P4 A  E+ |, G5 U* F8 F<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>2 Q' [$ i" \4 M/ D* l
<P>可完成对此项目的点击排序功能。 </P>$ k! o( l6 e5 M4 X  `& Q1 a3 [
<P>for(i=0;i&lt; m-1;i++) </P>
8 Z' G2 ?! M, e; L# S3 W<P>for(j=i+1;j&lt; m;j++) </P>8 M& M2 l% J' x1 z
<P>if(od) </P>
5 }- i: ~! q' @# z; _- s& D) C. Z<P>{ </P>' a" a% l  @8 n
<P>if(sg(ListView1- &gt;Items- &gt; </P>
5 h# a& l" l9 f& _<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
# A4 X, {& c% @<P>sg(ListView1- &gt;Items- &gt; </P>
2 G) r7 S; q+ `# ~  k6 H<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P># @5 u& _, I* F7 ^

2 T* G" R$ ?6 Y9 g4 ^<P>// ...以下从略 </P>, l8 |, {; A; X' n9 b* H
<P>  </P>
% l( ?9 P3 M. j/ g$ D<P>最后,删除临时的交换项目。 </P>8 M( x; X1 C; q0 K* q2 q; U
<P>ListView1- &gt;Items- &gt;Delete(m); </P>7 N. O) t  h) m  h7 D
<P>  </P>
3 @! i4 C) s# [<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>1 E3 G6 ]( i# p+ v* b3 D3 x7 u
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
( g* U2 Q8 a6 u4 g, y5 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, 2025-5-11 17:39 , Processed in 0.357835 second(s), 51 queries .

回顶部