QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>! @8 y# I3 c% o6 Q
<>  </P>/ I" t0 ~2 L+ C! H9 X2 J. Y
<>天津大学电子与信息工程学院 </P>; [! B' s; P" v
<>宋天宁 </P>, g5 a4 N7 l1 j2 D3 [
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>' S7 A3 ]( o( @* Q0 E
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
6 Y7 b7 s( p( N9 m/ U4 V* ~<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>8 t7 c4 `5 i, n6 p" F! k
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
2 ^+ Q7 \7 H& [7 A<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>7 ^! p5 V' x: R2 s
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>4 o/ B8 l7 T; X8 Z
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>2 q, I: ^/ u/ ?0 a& s' J
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
3 H3 s) @3 p9 }6 Y<>写自己的代码以完成这一功能。 </P>* K% K& h) P3 U! I( {$ y- d9 P% E
<>  </P>0 i7 H3 b9 ~3 M6 L- z
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
' t3 ?0 E) D. o9 h" N<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
: j) e# Q+ D. j: ?, s$ Z, X7 E) K<>内容以升序排列。 </P>
- a9 `3 C# s5 @: Y: D3 |2 A<>  </P>
, Y, K- D1 A6 M3 W  C<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P># ~/ q: `0 ^8 o2 b0 H8 V- G6 u
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
# [& L: y5 w$ r8 U8 A, I, K$ u<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>/ |* z6 i/ H- ^/ D/ h7 ]
<>包含子列和主列上的内容)。 </P>
8 H  k, Y3 R2 e5 k<>  </P>
5 O% J6 ~9 W% Z8 s<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>2 d4 g8 ^' {2 I( I
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>8 e: a! N6 X8 K3 L
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
) V2 `; I  r. G* }. V6 }- c<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
: S0 o7 }1 ]% {; g8 H<>  </P>5 Z$ E9 D! |7 Z0 X3 Z9 n6 i
<>  </P>& d. j1 r1 L6 y  ~* d
<>void __fastcall TForm1:istView1ColumnClick </P>
* M$ T5 F/ d! F  V/ S+ ]<P>(TObject *Sender, </P>1 {$ A& T# h# b; i& }9 M) U
<P>TListColumn *Column) </P>1 k5 _6 D. C- @
<P>  </P>
. K* S+ Z9 f+ c. J% N$ E<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
9 [$ T; z0 U; v+ I<P>点击的列的信息。 </P>
, |8 n  X0 U( Q! j3 @<P>---- 下面先定义变量: </P>% J/ N4 H+ O% W4 g
<P>  </P>3 U" N$ a$ x$ i. W
<P>int i,m,n,j; </P>1 m7 f7 y. t" w" L" d2 x
<P>static bool od=true; </P>
# C" I/ n; z2 A$ w' I  G  o4 _! z<P>od=!od; </P>% _! o6 h/ a/ i
<P>  </P>  d7 s7 `0 S0 }4 W) s
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>( \0 {3 s0 M0 ~! ~- [: D
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>  J/ v! I1 A7 e" E* Z. \- h
<P>列表框中的总项目数。 </P>3 m3 d% O. I& Z6 z+ ^' M! s" ^$ r
<P>n=Column- &gt;Index; </P>5 ?# ?+ A9 D+ k5 v4 p- v. n
<P>m=ListView1- &gt;Items- &gt;Count; </P>
6 Y$ E8 N( e7 O2 N: M<P>  </P>' _8 N8 g0 p" O( Z
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
" M7 X9 R) j/ l: w' C. U<P>ListView1- &gt;Items- &gt;Add(); </P>
; Y% T) \1 h4 V<P>  </P>) X% P; \( U: u# L- u
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
5 J: A/ w3 X% ~! z' T# e, K& h<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
% t# V/ i: [- K: U<P>if (n==0) </P>' H5 l! M; _! b  S
<P>{ </P>
9 ?4 d. y) k3 k0 g7 w$ I<P>for(i=0;i&lt; m-1;i++) </P>
3 j2 P, i# S3 u: z! `0 i0 ~# L<P>for(j=i+1;j&lt; m;j++) </P>( U, E! n/ J; X/ j) ^
<P>if(od) </P>
$ v* q( Q' u7 t) y; G% q0 k<P>{ </P>* W/ _8 p' l; q$ p0 p% m3 }
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>6 B' [+ ?# M$ s# {* z9 }
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>% ]. J1 ~8 F8 Z- y& h2 q/ f
<P>{ </P>
0 d6 M0 L0 [/ t5 U# ^- G# G<P>ListView1- &gt;Items- &gt;Item[m]= </P>
8 C+ L) I1 c8 s$ D7 z! t<P>ListView1- &gt;Items- &gt;Item; </P>, Q  {; r. `) P5 z' R, _
<P>ListView1- &gt;Items- &gt;Item= </P># M( c% Z+ _4 v4 y2 f
<P>ListView1- &gt;Items- &gt;Item[j]; </P>7 h- j+ _2 p0 D, S  {' J2 w
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
: B7 ]# f" t. \<P>ListView1- &gt;Items- &gt;Item[m]; </P>+ s5 q( N1 s9 M
<P>} </P>
2 T* S$ F. G0 l/ H7 b<P>} </P># r. d& B- {, a, {; h4 Q0 h
<P>else </P>; k* U# z6 l% M' X
<P>{ </P>& w% E  H; I7 L; V2 r( k- x2 L. i
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>5 G+ u9 ^- C4 Y8 [  h& T6 u
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
: A$ }* j' Z3 @; E: m' Y<P>{ </P>
4 ~: b$ b, N$ {- J) _* h+ ^! S7 B<P>ListView1- &gt;Items- &gt;Item[m]= </P>5 r! V$ y, q  I% @; n4 s, u
<P>ListView1- &gt;Items- &gt;Item; </P>! Y) ?: [$ T' N5 b" x
<P>ListView1- &gt;Items- &gt;Item= </P>
. X( A  U9 A4 v+ u<P>ListView1- &gt;Items- &gt;Item[j]; </P>% I" ~- g! j0 i
<P>ListView1- &gt;Items- &gt;Item[j]= </P>0 `: I2 c0 x+ q2 \6 F
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
! z+ b' X% u' K- Q8 h. e2 ?6 M' |<P>} </P>
, _$ y% f7 U+ c( R- e( B' o. Y<P>} </P>3 {) _# i3 |7 v. c2 x2 @1 y$ W
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
2 t( |  w: M/ V" Y2 S7 i; [4 o<P>return; </P>
' f, v! T8 c$ |. l- _; f/ s<P>} </P>0 ~, J  g# `' y! W
<P>  </P>
' f8 a0 t& q5 {! n0 a<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>; d# o1 M8 O; t- D- \
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>( F- C2 M) c! L% ~5 Q" s9 S
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
1 |2 }; r! b( J& v8 B4 V, T<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>, ]$ G* ~( }& g6 I% ~
<P>ListView1ColumnClick前面即可。 </P>" z; R* r( C" q! u2 E/ q( |
<P>#include &lt; vcl/dstring.h &gt; </P>5 U+ K5 H# u  ]3 j
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
$ G' m9 C& e$ A* l2 B6 }<P>{ </P>
7 k; T8 f: ?' J1 Y- U. ^& p<P>int l,i; </P>/ x7 q+ |+ S5 |; ^& W
<P>AnsiString qq(str); </P>& D8 c7 V5 N- ~4 r5 `
<P>l=qq.Length(); </P>/ R- p8 @% J6 o9 }0 K% o+ }, [! p
<P>AnsiString p(str); </P>
. \1 P% l$ d. K& m! e<P>char a[]="\r\n"; </P>2 s, n1 X: n& L" ^
<P>int j=0,k=0; </P>. v: B/ a8 f& Q% }3 B1 K
<P>for(j=1;j&lt; l;j++) </P>
8 E" W3 z/ ^5 T5 [( m" P) {<P>{ </P>
3 {+ l% g9 b) C9 X! ^+ e<P>i=1; </P>5 S. j; D) a0 L$ o1 T
<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>/ H7 A/ E" \5 k# \1 Z/ |; E
<P>{ </P>' i: q1 }2 U! i) g0 T: M5 t
<P>p[i++]=qq[j]; </P>  a( X" M* B" X( r
<P>j++; </P>) ^7 J, G" d+ t7 V
<P>} </P>0 X8 d5 Q- A8 K- Q; o
<P>k++; </P>
4 P3 A8 G" L8 v  m" [<P>if((k-1)==n) </P>
1 W  o; F! q8 c- V  _- g7 N<P>break; </P>
8 b% `) I4 H2 R, K" V4 a<P>} </P>; b8 a" X) }% t/ l" @. [& O
<P>p=NULL; </P>
. k) V( [6 S) J" I/ L- D<P>return (p); </P>
& `' `2 ~9 n4 t( K9 f0 H! e<P>} </P>
" D$ j& J2 r" Z7 x, s% D<P>  </P>- B" R( P/ c" k9 s% @
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>5 ?+ H+ Y5 A+ g" v
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>% i' j$ m5 d+ F. e
<P>可完成对此项目的点击排序功能。 </P>
+ i& p$ Z1 y9 ~6 Z+ v! v* ?; J. b<P>for(i=0;i&lt; m-1;i++) </P>* o- l* L, H( \3 _$ Q8 }
<P>for(j=i+1;j&lt; m;j++) </P>0 }) e! O, L) F, I# K
<P>if(od) </P>
2 H+ s4 Z% j. E1 s7 d4 p/ f3 @<P>{ </P>
& L8 t0 N6 E$ m* M<P>if(sg(ListView1- &gt;Items- &gt; </P>, H* `4 r! i* |0 |# I
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>: E0 m5 D* {. K4 ~7 M: }. Z
<P>sg(ListView1- &gt;Items- &gt; </P>3 b0 l8 O9 Z4 k
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
) T# K% J; `; }% f
3 s" m0 w* o4 a: b: I0 q( r4 z<P>// ...以下从略 </P>
+ B; r; R9 k: z7 {2 ]( o1 ]<P>  </P>
5 A: F! ^/ H& W6 b; B) m<P>最后,删除临时的交换项目。 </P>& |# z9 ~1 f, }. ^" K
<P>ListView1- &gt;Items- &gt;Delete(m); </P>2 s+ n$ S/ w- _) ?3 f: o' ~/ Q
<P>  </P>, h- a+ F+ f9 e
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
! m3 I3 t& a' m) U$ {<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
9 X' y$ p0 l; l$ j: K' u<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 08:39 , Processed in 0.441121 second(s), 52 queries .

回顶部