QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<>  </P>
% [! e$ r6 i- {$ R5 s7 R# A6 Z<>  </P>
4 H( e7 i9 O: Q5 Z; y2 m; @3 W  U<>天津大学电子与信息工程学院 </P>+ q( x; e& A9 l, z( x
<>宋天宁 </P>
/ c, l- d5 `, A<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
7 M  U2 v# a7 c- {) M9 a8 f<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
8 u# ]3 z% N2 T( U% ]<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
, q' U3 p! E" M. U- @6 j% H<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
1 y' V+ W& ^, N$ [9 o  m0 H, F<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P># x' K* @  [" S2 I. U8 y
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>7 R2 x4 y" e8 D* c" C' h' o5 R. ^
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>1 ~  v/ p% @, }
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>7 p( k. \5 p  @8 c8 |' _
<>写自己的代码以完成这一功能。 </P>
) O* \7 G- \' C* @<>  </P>! q& }; b5 J' {2 t5 ^/ N8 o& g
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
8 [. G* e+ t- f* }. a9 z5 \6 {<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>$ C6 F+ _- [+ H
<>内容以升序排列。 </P>( F: J/ {7 J+ L
<>  </P>1 e+ g' K* O1 S4 }
<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>/ }# ]& n( U5 n4 |8 E" }! W
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P># k$ C1 G' Y! _+ l
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>' v: U' R: n9 C. K, e8 q
<>包含子列和主列上的内容)。 </P>  t: g. {  b3 @9 T) ]
<>  </P>% _( v/ {; Z  m
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
9 k1 r  \7 o0 f7 q# q  U2 X2 o<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>9 l* c0 ~0 e- \. o- K5 @3 |& T
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>; c- r3 T3 t# N9 S) p/ Q$ l+ D( n. j
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
4 w6 y! v& f$ K# P9 m6 B<>  </P>
, r/ b/ l9 L  W9 |# r, ]<>  </P>
4 Z0 Q9 F2 q8 |4 b% O1 Y9 q' G<>void __fastcall TForm1:istView1ColumnClick </P>6 f( _9 b% W" T4 h9 `
<P>(TObject *Sender, </P>
4 O& F& H1 r* N+ p<P>TListColumn *Column) </P>. g+ ~* D4 S: A6 c3 Y
<P>  </P>; E- y5 t; w8 a: j6 y+ V/ V* n
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
7 k' c" s7 J6 n$ [3 ^' X9 D- T<P>点击的列的信息。 </P>/ I8 h$ n5 J/ f9 M& ~' |
<P>---- 下面先定义变量: </P>
# H5 N& @. {4 a2 T% F4 \, S<P>  </P>
: Q6 z  }' w$ Z0 `7 e9 ]<P>int i,m,n,j; </P>7 u# k) L- @: g* B  s- N3 ?
<P>static bool od=true; </P>, X' s" o$ q8 O1 ?% k
<P>od=!od; </P>3 S. a0 m5 y: V/ I6 R0 J  r
<P>  </P>% _7 y" N4 b" @3 C" o
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>1 {: j+ N$ d( w4 P
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
! k9 b! J* b$ l  e5 ^& a<P>列表框中的总项目数。 </P>' }7 z3 `5 }7 B; I) I8 B
<P>n=Column- &gt;Index; </P>7 M6 d- A, R! s$ I: Q  l" d/ l4 Z
<P>m=ListView1- &gt;Items- &gt;Count; </P>
2 s, g: z, E/ D+ W) Z, v6 i: E<P>  </P>: f, M3 c" E: B4 u" |
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
- F0 h/ j1 y- j6 S4 F; d! A<P>ListView1- &gt;Items- &gt;Add(); </P>( f1 q! @" v) w* s1 Y
<P>  </P>
7 x2 R( X6 w9 ~  H<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>  Q) G; I; I: t! R+ X( l. @
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>% E' G, f. R  k/ \0 C, Y
<P>if (n==0) </P>! R1 ]8 x% Q* `
<P>{ </P>
9 @+ m- Y6 Y0 p- n; u! X<P>for(i=0;i&lt; m-1;i++) </P>/ U. c/ h/ e  f/ @' ]
<P>for(j=i+1;j&lt; m;j++) </P>
, n$ B4 f; d) m<P>if(od) </P>
/ @+ t3 i- t4 }: B' @5 c6 A$ E<P>{ </P>
* O+ l$ }8 h7 T1 |5 ^2 p7 L<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>
  P9 I8 J% U  K- s- a<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
4 X' @" l/ B5 Z2 k<P>{ </P>
, M% ^6 l6 I3 l3 E$ r, g( }  k, E6 I<P>ListView1- &gt;Items- &gt;Item[m]= </P>$ h. w& k- I" e- \; ~! [
<P>ListView1- &gt;Items- &gt;Item; </P>
2 Z' Y) F7 [! b: b+ a* k8 a<P>ListView1- &gt;Items- &gt;Item= </P>
4 a2 `) o1 K  f! f<P>ListView1- &gt;Items- &gt;Item[j]; </P>
- @8 o4 v+ k4 ?( `<P>ListView1- &gt;Items- &gt;Item[j]= </P>' v# |0 K0 o6 N3 R9 |
<P>ListView1- &gt;Items- &gt;Item[m]; </P>0 |$ l& U- @5 U6 P. I% ?* H9 f( y$ R
<P>} </P>0 K% f7 B# z) R- _6 |! }5 i, p
<P>} </P>7 h( g  h& v) ?/ z. Q; z& r$ V6 i4 |
<P>else </P>5 ~" k! \5 p/ L( ?
<P>{ </P>
8 o2 t5 q& y8 W: K/ z. w" Z) j5 B<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
& b1 {( T" K; b, h<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>! {6 \3 S7 f, p9 S: d9 T( n
<P>{ </P>
8 m: y" R1 h2 X<P>ListView1- &gt;Items- &gt;Item[m]= </P>
+ [0 N5 |: a2 M0 U1 h; P' C<P>ListView1- &gt;Items- &gt;Item; </P>; P) Q" U' i. [' B  M$ K
<P>ListView1- &gt;Items- &gt;Item= </P>1 o& v$ p; g0 V9 X: W2 S
<P>ListView1- &gt;Items- &gt;Item[j]; </P>7 ?" L6 o$ x5 H
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
1 D% U4 y+ f  T# _<P>ListView1- &gt;Items- &gt;Item[m]; </P>1 {8 ]/ `! o/ {% @8 q$ k8 B
<P>} </P>6 I  E. R- v& c9 E$ k
<P>} </P>
; w! M* i# j& Z* |" S( |3 ]+ O<P>ListView1- &gt;Items- &gt;Delete(m); </P>; |. Q5 }# b) D2 D6 B
<P>return; </P>
3 k9 V7 @$ W( z; t! x7 h<P>} </P>& q( m% m5 y" ?( d
<P>  </P>- s- B, \! l4 {7 x- N; `
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>- u2 ?3 {1 ~8 u, c, C& a1 |
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>" P$ M1 i) E; B* @; N
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>8 X$ W4 S8 U% C8 y
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>- ?- _' G, e  N
<P>ListView1ColumnClick前面即可。 </P>' u! t: y; }2 L/ e! J
<P>#include &lt; vcl/dstring.h &gt; </P>& X4 ]" c" i* Z( ?. Q- Z
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>/ u" j" i6 n: m7 v
<P>{ </P>2 u: y$ v/ W( M' }
<P>int l,i; </P>' e$ D# v: q# q3 s& [
<P>AnsiString qq(str); </P>
2 X) E  t8 I9 i6 ]! X<P>l=qq.Length(); </P>6 E. Q: A) Q  R( ?" t
<P>AnsiString p(str); </P>
0 K3 U6 w. @) T- v<P>char a[]="\r\n"; </P>
) @8 w& m1 b! U* L" C9 b<P>int j=0,k=0; </P>7 `9 ?% \+ D; G( M+ H3 O$ ?( O! L7 h% @
<P>for(j=1;j&lt; l;j++) </P>
6 h$ x( R/ q$ l$ [* m<P>{ </P>( x; P3 ^+ b3 d( F, E
<P>i=1; </P>
+ m+ N1 y5 w8 I" q& @# _<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
. n9 ^+ Z3 q& `6 U8 B<P>{ </P>5 J( z: m1 A* r$ e2 x
<P>p[i++]=qq[j]; </P>+ {8 ]3 H# Y7 r  C; w
<P>j++; </P>- L- N5 n' o; o
<P>} </P>
7 g/ O' c, \; j! E% A% [<P>k++; </P>
( E  y1 _1 K" a<P>if((k-1)==n) </P>& n  H9 K2 E0 A4 v' o' b% G
<P>break; </P>7 B- c5 h5 k' P# J" W/ J# C; [
<P>} </P>
( x- p  I% q- _( l3 _/ z<P>p=NULL; </P>
* R: I$ _, g$ N; p8 K<P>return (p); </P>
2 `3 s9 K' ?+ e: W& }; q: d$ u<P>} </P>4 U" n9 y5 F* o# v: M; d% @4 F
<P>  </P>
/ z, @4 I5 V- w+ t& T' @, Q6 j8 O<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>+ t/ M( o& j' a
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
" w( a  ?- U2 M<P>可完成对此项目的点击排序功能。 </P>! ~) \6 f- I' L" q( m( o- F0 O4 U/ \
<P>for(i=0;i&lt; m-1;i++) </P>: p# K! ?' i$ L. P  a6 [0 X
<P>for(j=i+1;j&lt; m;j++) </P>  X& r0 b, X1 K% q: J
<P>if(od) </P>
. `( S( @' T7 L$ h2 b7 ]<P>{ </P>  E3 }' J1 ?4 T
<P>if(sg(ListView1- &gt;Items- &gt; </P>* N% j; w' t. f$ r
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>2 h7 s% H5 }; K( @3 u: g; p6 `. L
<P>sg(ListView1- &gt;Items- &gt; </P>, ^; I( _- r7 k9 D
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
+ b) d: f! ?/ `1 O2 ^2 V7 W: \) x2 G/ \/ m1 @
<P>// ...以下从略 </P>* H: x& n- c7 l! h9 r* M' [# g
<P>  </P>
/ p5 x* s$ v3 {. \<P>最后,删除临时的交换项目。 </P>5 x+ U) V+ G/ E& \- Y- _, Y" t
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
' o# U- d4 M% F6 v% ~( `$ C<P>  </P>+ O& U, x; v7 v  t& A- Y$ a
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
  @* W7 U2 q- S# g% c1 w: ~<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
- |  O3 w. y# {# E' N0 f<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-23 02:00 , Processed in 0.640459 second(s), 52 queries .

回顶部