QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>% C7 T* u7 a$ w/ B8 h' D
<>  </P>
, B0 }& A0 s8 {- D( j3 g9 z8 R& _7 `<>天津大学电子与信息工程学院 </P>7 I9 ^5 r9 l: o: {8 M& L4 m& }
<>宋天宁 </P>: f0 U" }/ Z0 Q1 _$ T7 n) q- m! o
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
, K! x8 @1 ]5 u' k0 S<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
$ h. u& X* ~- P+ ^* Y' g- b<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
- _3 Z* e6 \! J+ p& k<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
8 v& e4 N5 A, s  d% r/ F<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>7 L; W& r: j/ U5 ^* {, |8 F
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>' ]; h! G% H# c1 f# m( w2 J
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
# b9 h9 [3 d. o4 v$ o$ }' A  l<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>, e, P3 P5 h0 n$ R
<>写自己的代码以完成这一功能。 </P>
% \% {+ w: U  M8 v2 a- r<>  </P>
' @  m0 K: c6 W! y<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
' f8 c; o- @4 c) B<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
0 F' w) d$ ]+ k9 P- g" z' a<>内容以升序排列。 </P>& t5 @$ ]! l% ]/ G
<>  </P>
6 V" I) V1 p6 D- Q; c+ C5 o<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
2 ?7 ~3 ^  F% F! [& F1 G0 K: I<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
2 r* X  x. D( _% i0 j1 a<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>* u0 w) ~/ d5 L) g# T6 e  E! ~
<>包含子列和主列上的内容)。 </P>* Q1 h# L9 N) [! u- k
<>  </P># }' o; l3 j$ {% K; @; {
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
! G! ^1 l& u$ _6 z1 a<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
2 G/ _8 v+ N# z( D2 `) d<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>* g/ T6 X1 N3 P9 o3 z& [, L
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
$ I, W$ k- H' G6 r<>  </P>6 r# Z$ p  X( ^! D
<>  </P>3 t7 x1 g9 @% F# G% ~  @3 T  z5 x
<>void __fastcall TForm1:istView1ColumnClick </P>
* y& e; |! R# U$ y- j<P>(TObject *Sender, </P>
( |2 D$ Q$ g# Z6 K8 Q2 M% j<P>TListColumn *Column) </P>% |8 {* {1 O6 |' I+ F
<P>  </P>, H: N) n; \. Y! c# H6 u
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
# b4 h6 }4 X; P4 q<P>点击的列的信息。 </P>
9 W' R) M8 f, U) e/ v<P>---- 下面先定义变量: </P>* F3 \- _) v( _. c  f
<P>  </P>; Z, x4 i6 o6 J/ S2 r
<P>int i,m,n,j; </P>8 Z5 V8 g# R- P
<P>static bool od=true; </P>; x* s7 }0 ^9 W0 @$ q
<P>od=!od; </P>
- m! Y$ l/ D; |( o: g<P>  </P>
7 t6 T- p8 t  d7 M' h4 e# V+ j- r<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
  E7 E7 C% K( N8 O$ n' H<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>& r+ _) ?. D5 w
<P>列表框中的总项目数。 </P>/ ^/ f5 ]0 ]  [: ]* o+ ?3 g1 C# Q% E7 \
<P>n=Column- &gt;Index; </P>
, i+ B6 C. J' E& h% k$ C2 [<P>m=ListView1- &gt;Items- &gt;Count; </P>1 b! x7 U+ k3 ~1 V, S
<P>  </P>
3 l9 v, a% [. ~$ T+ A! l<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
4 E; m( w) q1 d. S7 v3 E<P>ListView1- &gt;Items- &gt;Add(); </P>
5 X3 S4 `2 C1 Y% v<P>  </P>
3 r; z0 `9 b: Y8 ?( d5 v<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>+ w- h# y3 v5 n2 D9 B/ ~+ j( i
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
& ]/ e( o7 K: Z+ K3 Z) a7 K<P>if (n==0) </P>
9 l- N8 g' w* h2 p<P>{ </P>. Q1 [$ q3 U( D( Q8 R# c1 [5 H
<P>for(i=0;i&lt; m-1;i++) </P>, Y& @7 U& X8 Z  z$ O
<P>for(j=i+1;j&lt; m;j++) </P>9 q- o- u* u, \2 t
<P>if(od) </P>
& m' M' X' |' s<P>{ </P>
7 b8 U0 Z+ {- S2 h<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>7 L' J0 {0 f2 {( r+ \8 p& R
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
/ \+ q6 q; M5 U  [; r+ N1 Q8 ?  o% o+ w7 G# ^<P>{ </P>
. v: @7 x( i8 I' [7 @% R* Z* Y<P>ListView1- &gt;Items- &gt;Item[m]= </P>
4 c/ a1 i! j1 y<P>ListView1- &gt;Items- &gt;Item; </P>
1 B; U% X0 _# D' w  ]5 N" z<P>ListView1- &gt;Items- &gt;Item= </P>( N; o5 n8 n( F# S6 h3 m( b/ l
<P>ListView1- &gt;Items- &gt;Item[j]; </P>/ b% u$ c; [  W- ^4 h
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
1 [4 |5 U4 y9 }7 d9 X<P>ListView1- &gt;Items- &gt;Item[m]; </P>
& x/ W0 R* W8 L) Y<P>} </P>
% `9 M5 N; w/ J5 `6 R; n' `/ N<P>} </P>, w, p4 t2 B! g. D: `
<P>else </P>, d! k3 p# {7 E# N4 @
<P>{ </P>
' @: s8 N! E+ M4 i8 \$ L& k<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
2 B0 h1 }+ D' J<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>' h" y" J! ~. ~6 n8 ~
<P>{ </P>3 e1 u, |, K$ ]5 D! Y* f- ^+ o
<P>ListView1- &gt;Items- &gt;Item[m]= </P>! |/ x; _7 v" r' s# S- Q! I" ?
<P>ListView1- &gt;Items- &gt;Item; </P>
. F# Q- T/ s! ~5 `: Y; S<P>ListView1- &gt;Items- &gt;Item= </P>
, q( a; x# Z* d. r) H" W' h# B; C<P>ListView1- &gt;Items- &gt;Item[j]; </P>
2 G+ S; @6 \- f2 ^5 {2 ]<P>ListView1- &gt;Items- &gt;Item[j]= </P>% T8 a' s5 }+ h
<P>ListView1- &gt;Items- &gt;Item[m]; </P>$ X1 U6 P! h3 L! c% y/ e. L
<P>} </P>; ~+ K4 f( z3 p/ \7 h
<P>} </P>
" L) L+ Y8 Q( m, r4 H" B. k<P>ListView1- &gt;Items- &gt;Delete(m); </P>
: R9 f" E/ }! ^4 x3 s/ e" A0 f6 i<P>return; </P>: j) c: Y8 a, W) B( V
<P>} </P>0 r4 Q2 H; y. e0 ?* `
<P>  </P>
7 o2 u3 P" k3 u6 X<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>0 m7 F5 g9 Z7 _. W
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
& h" A" g0 H9 V8 x$ i9 ~<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>8 I- F; F( T- m. k4 c* P% O
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
1 R5 G, O% ]0 B! e1 z! t9 }  E0 ]<P>ListView1ColumnClick前面即可。 </P>
; ]0 L% y* ~! p, {" @# }9 t4 \* _8 x; [<P>#include &lt; vcl/dstring.h &gt; </P>4 E! H; V  W7 t# n& }3 [7 e
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>+ u3 [  `, m" B- q& v+ r* Z
<P>{ </P>
! q* t! ]/ R  f, L7 S7 h7 u<P>int l,i; </P>
$ d0 X/ Z+ f+ Y2 n2 ]. w<P>AnsiString qq(str); </P># A0 I0 I' ?* Y7 k/ e, U' Q% N' ]3 [
<P>l=qq.Length(); </P>
( ~7 m8 @2 Z5 ^5 n# F& a- ~* s! u" B<P>AnsiString p(str); </P>
/ N7 d% A* B- l4 ~<P>char a[]="\r\n"; </P>
; d% {+ b' u1 S* u<P>int j=0,k=0; </P>
  Q( @$ S0 }9 {* W9 Y- q1 H" \<P>for(j=1;j&lt; l;j++) </P>1 a& R  L& F# R# f0 ]- s" G
<P>{ </P>' H. H' G+ l$ X* y3 l9 W; v
<P>i=1; </P>
( d: X  q6 P. u$ O6 G<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>  |: f6 d9 p1 @( G
<P>{ </P>9 b4 ~. H. ?4 F
<P>p[i++]=qq[j]; </P>. L1 f+ ?/ C* z0 {
<P>j++; </P>
  I3 e7 \+ s) A' @! S; [<P>} </P>
- j* L; v5 g+ H<P>k++; </P>
9 X$ _# T: @, u4 P<P>if((k-1)==n) </P>
8 s2 V( l) ]! g, _<P>break; </P>( [! ?8 p8 i! x
<P>} </P>
5 @6 Z1 V7 }7 m<P>p=NULL; </P>, [, }  y- X3 q
<P>return (p); </P>: m6 b/ D! E0 `9 W
<P>} </P># A5 d& g0 W4 A# k
<P>  </P>
) `/ b9 |5 w2 G& G# b- f<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
8 R8 z# b: M5 C+ c7 _<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>8 d* n9 z3 V8 S1 N2 q1 z
<P>可完成对此项目的点击排序功能。 </P>
+ O2 ]2 j1 g& z<P>for(i=0;i&lt; m-1;i++) </P>& l3 R" e" X: A- P' i
<P>for(j=i+1;j&lt; m;j++) </P>9 R; L4 m, z8 t' _2 l; F* P8 a! U
<P>if(od) </P>
% P2 t1 I6 S' U0 @<P>{ </P>& q8 g9 e; s/ m9 O2 j, X3 n1 F
<P>if(sg(ListView1- &gt;Items- &gt; </P>( y! V' p+ ]' P3 @$ Q1 R% X
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>+ T& C  w1 u3 o7 H" Q- C$ ?. s, B
<P>sg(ListView1- &gt;Items- &gt; </P>1 x8 b9 O8 _  {
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
8 d# {. G, b+ I# }( a3 r2 X$ Q6 C9 J5 u- g$ x7 v8 ~
<P>// ...以下从略 </P>
8 K0 g6 n* Q6 {<P>  </P>
$ u0 l" r# r2 T1 x<P>最后,删除临时的交换项目。 </P>& X( k8 f  |& S3 g; L' [1 _* R" ?
<P>ListView1- &gt;Items- &gt;Delete(m); </P>4 {5 d+ H9 e. _/ N) e
<P>  </P>
" P) \/ y5 U$ h7 L, G<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>% I' x2 q8 ?8 F# S3 V( \0 t
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>: _% @5 ^- C: T# C' r
<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-7-28 16:01 , Processed in 0.384527 second(s), 57 queries .

回顶部