QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
7 Y& b9 h& D! A<>  </P>! J2 A# @5 ], E* b6 ]$ i
<>天津大学电子与信息工程学院 </P>
9 ~  F6 K' h1 W' ^<>宋天宁 </P>$ x% V9 V% e8 W0 Z/ H( j. l
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>$ \( [( r& M% j+ c
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
: W7 y0 R0 e6 p7 [<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>8 E6 l. v$ g) D+ \
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>* _7 R- k3 f) S  i5 V! A
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
6 }1 h  O! }: b<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>$ D% P, Y( Q/ _* l+ x4 x. U
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
/ x3 f4 K& H4 ?<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
' i0 Q, d' e4 z2 x- O<>写自己的代码以完成这一功能。 </P>
/ h+ R+ q' U3 ]( d2 l<>  </P>
  @1 s, `2 z' B5 G: e<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>" `% R5 I0 R  Y! S. s2 M- s
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
6 K5 q* @. F% o) u2 ?$ C<>内容以升序排列。 </P>- m& c$ F0 Y  {3 w4 p7 i, q
<>  </P>
- G9 D6 M4 Z& m<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>4 P5 E" Z- m6 R7 B! K
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
7 m/ g" X  v$ t% H. O% b2 B4 \<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>5 R0 V- ~: U3 Z% J8 l% G
<>包含子列和主列上的内容)。 </P>
9 g% R5 A2 {& S1 h$ P<>  </P>
: D. `2 ^4 ]: C  }7 {& G<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>  k0 l' A" J/ p# L; p
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
: B+ h) _7 J7 }  h! E; K! U- ?8 f<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>6 s6 ]$ s4 B7 u1 B3 G0 h
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
  T& k0 U$ N" d/ I$ k: v; P4 [. A$ N<>  </P>
1 K) N$ ], e' A* t2 A<>  </P>2 s! V+ @  I5 r7 X# ~1 Q
<>void __fastcall TForm1:istView1ColumnClick </P>
/ r9 `, O1 K: g" ^! h" x<P>(TObject *Sender, </P>  F9 E( _7 {( Q( T+ x* h
<P>TListColumn *Column) </P>
+ p/ `1 n" |8 J' A+ x( A" q<P>  </P>
4 L1 L# R* m5 [<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>6 E! N! O' T5 I$ x( ?2 V* S
<P>点击的列的信息。 </P>- t% ^/ v4 h( w8 m" x& j5 o
<P>---- 下面先定义变量: </P>& N' ^8 m' i9 N. D- F( |
<P>  </P>' k. a7 z, [) R) _' I5 N
<P>int i,m,n,j; </P>* ^0 j+ S' F4 e* |& M4 D
<P>static bool od=true; </P>+ L! Q, [7 u5 o3 @
<P>od=!od; </P>9 }$ b, I; O& U9 a" Q' x! m" B
<P>  </P>$ E% ]. P: N8 d
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>: P+ i% p# U# x
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
, H( x7 f$ b0 _2 }) T4 ^, f! v<P>列表框中的总项目数。 </P>1 ]6 I' n8 M. ?2 H" E1 X" s' n
<P>n=Column- &gt;Index; </P>" K7 ~8 B3 G, J+ S
<P>m=ListView1- &gt;Items- &gt;Count; </P>
! _; q7 I# D  d4 a8 }2 c<P>  </P>. z5 o$ h; C- b: J
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
/ m4 N7 [. |, y' L  Z<P>ListView1- &gt;Items- &gt;Add(); </P>
( d9 ~6 l/ w2 T6 s- Q3 R<P>  </P>
! J' t- ?) g7 T# `: n- U6 [$ j<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>9 S# M5 w- o) M$ `
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
4 b& M# j! l* r6 E' a9 i, V<P>if (n==0) </P>
0 O& ?7 V  v8 f& ]" F<P>{ </P>
: N% _+ k6 M6 q4 h1 U<P>for(i=0;i&lt; m-1;i++) </P>5 ~" ?1 D8 D  h( B
<P>for(j=i+1;j&lt; m;j++) </P>5 W0 p5 s0 `4 {
<P>if(od) </P>
( o2 G$ x$ E) J2 O/ k  j<P>{ </P>0 ~7 O$ O, y/ ^% g8 v8 b% y
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>' J  j' W6 X6 [* c
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
% V, E/ u1 e: @. x1 ~<P>{ </P>
- V4 E& \* A! L, |% C/ t: S<P>ListView1- &gt;Items- &gt;Item[m]= </P>* ~8 l6 G" K5 O& w7 b( D0 C
<P>ListView1- &gt;Items- &gt;Item; </P>
; y# d9 ^( ?; H; ]% M$ G" a" D<P>ListView1- &gt;Items- &gt;Item= </P>( x% y- ?, m8 {, D+ u7 i
<P>ListView1- &gt;Items- &gt;Item[j]; </P>9 q) ~) t; D) R7 k9 ?) U- |% b
<P>ListView1- &gt;Items- &gt;Item[j]= </P>: i6 h$ h2 v( l" x% o
<P>ListView1- &gt;Items- &gt;Item[m]; </P>) s# V# V! c: L: c9 H3 }% M1 [
<P>} </P>' [5 D% ~8 I+ K: u  f
<P>} </P>+ R1 ~8 h1 Q7 B9 t8 W& \% W
<P>else </P>
" @' B. b  u- V  y<P>{ </P>
" \3 s* x; a& O<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>1 s4 E* f; j( Y" F
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>' i5 h# A% u* o& u. F  |
<P>{ </P>4 F% Y) r5 r4 u
<P>ListView1- &gt;Items- &gt;Item[m]= </P>6 R1 u& s, J. ^" ]; m
<P>ListView1- &gt;Items- &gt;Item; </P>+ E7 M* J0 i% ?: `1 D3 ?! l9 P
<P>ListView1- &gt;Items- &gt;Item= </P>
& z1 o' N. F' A( [5 _) A; L9 u; ~. H<P>ListView1- &gt;Items- &gt;Item[j]; </P>
( u! W& c; M) g" }( k) A<P>ListView1- &gt;Items- &gt;Item[j]= </P>7 L# w0 N( h3 b  q
<P>ListView1- &gt;Items- &gt;Item[m]; </P>) t6 g0 y2 r) Q
<P>} </P>
; y. p" u  e  A- S- C7 ]0 p: Y<P>} </P>
; g% f( P1 }* N) v% \8 r<P>ListView1- &gt;Items- &gt;Delete(m); </P>
5 S5 y6 c$ q+ W7 |<P>return; </P>
+ B2 _# B7 k  b8 Y$ C( i) b" Z) f<P>} </P>- p9 d8 y9 I- Z9 v- ?
<P>  </P>
; H$ @3 l+ d& b<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>) O8 }4 {3 C% F/ Z
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>" k2 p9 _4 z8 `8 n. K+ y( C7 }
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>' `+ t4 g* M2 \" h5 S) _
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>. J/ N5 a1 G# q% h. a
<P>ListView1ColumnClick前面即可。 </P>
, x. Q# ^+ T& w3 t5 ^* u4 D<P>#include &lt; vcl/dstring.h &gt; </P>6 x- V( C, c4 A
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>0 N' G+ l/ x0 [  E
<P>{ </P>
# }3 X/ N& }1 H<P>int l,i; </P>
9 ]! g; t$ p" u2 x. X<P>AnsiString qq(str); </P>) B+ E( u( N$ K3 o1 |6 U
<P>l=qq.Length(); </P>
: f( \. V0 f+ N( o<P>AnsiString p(str); </P>
  k* h: r8 B6 e! \. b& m<P>char a[]="\r\n"; </P>
% m; H. d& P( ~" g4 A2 ]<P>int j=0,k=0; </P>+ q! V# @3 x* |& b( Q
<P>for(j=1;j&lt; l;j++) </P>7 P- N0 o6 Y, c9 y( H
<P>{ </P>, x. \# S+ W$ e$ _- U( }7 a
<P>i=1; </P>2 y! G' y! s4 l7 z$ i) F
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>$ a* V* z5 l5 _& W
<P>{ </P># h3 F5 h- N4 G6 _+ v
<P>p[i++]=qq[j]; </P>
& Q' C4 a$ D) S$ \<P>j++; </P>
! w9 @- N* ]; T8 p3 f) O<P>} </P>
. _% T9 l& u/ S) O; m% m0 p$ [<P>k++; </P>) H: Y/ c8 W2 H; m- Z
<P>if((k-1)==n) </P>$ W3 ?( ]. T6 N7 J$ t, I
<P>break; </P>: q  C/ |! a( m. g" a/ K  F
<P>} </P>: J  Q5 o' l' M) d" C
<P>p=NULL; </P>" o& K7 k0 Q; k( B3 k
<P>return (p); </P>
% T0 i, y; K* D/ `4 |; C4 L. n<P>} </P>) `( a: c# E+ \, u6 e& ]1 a5 L7 Z
<P>  </P>
6 g! y4 `" k; B2 {& G<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>+ U3 |- A1 y  x0 M
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
' L$ Y$ \  \% R# @" Y7 i2 w" h% Z<P>可完成对此项目的点击排序功能。 </P>2 j. F& T" c  K4 H" @; ?# V
<P>for(i=0;i&lt; m-1;i++) </P>
$ R* Y4 k. x5 |* S( J<P>for(j=i+1;j&lt; m;j++) </P>
9 k+ A% k/ x! d9 P4 m3 @<P>if(od) </P>
! Q& ]9 Y" m- U( \<P>{ </P>8 ?' N9 f* {" ~, D4 q1 e
<P>if(sg(ListView1- &gt;Items- &gt; </P>6 H" [4 A( [+ t; Q
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
; O) K; z7 P+ t2 ?+ V<P>sg(ListView1- &gt;Items- &gt; </P>
4 I  q4 y% K6 V8 b" i0 y<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
* P' {4 c4 v( Y9 F9 @' i- T7 o
<P>// ...以下从略 </P>
3 e/ w6 e$ b8 {& j+ ?( e<P>  </P>
; D. J3 M2 Y: C' }+ m. H, }<P>最后,删除临时的交换项目。 </P>
9 P: {; [5 j3 w0 J& O<P>ListView1- &gt;Items- &gt;Delete(m); </P>" w; j; O! r$ [+ u' F, z/ _1 F; I
<P>  </P>
1 y# Y$ G( D% }4 B1 c7 I<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>+ Z* s/ B9 [0 Z5 X: o1 ^# k: G8 @, E) u$ k
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
" A- j4 ?' s. R/ y<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-4-20 21:28 , Processed in 0.446292 second(s), 52 queries .

回顶部