QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
- }$ d% m& P% A  v<>  </P>  `$ `! J0 j6 ?+ `- J2 w: g( S
<>天津大学电子与信息工程学院 </P>
6 j$ S# o' l4 d4 i( v<>宋天宁 </P>
; F/ e% N+ M0 s% n<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
9 F4 ~* j  ?, Q+ d3 ]<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
8 g8 U- t' ]* s  E0 o<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
7 C$ j: v6 n( q$ _* Y& N. v<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>- d. k# ^$ [1 E
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
5 q6 e& k# i- x1 ]3 G, a<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
5 T& r! y# C, `6 K& N2 L<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>1 J/ q" p1 M& O$ Q2 e
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>& w) j0 F( K5 h4 O- H) F* k$ x4 N3 y
<>写自己的代码以完成这一功能。 </P>
6 ^5 e- m% c8 I6 c, _<>  </P>
: o% `* ^$ [2 |) ^<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>0 i' p8 f( b  x: n6 A2 r
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
/ ], B/ p8 i% O1 ]: c5 P<>内容以升序排列。 </P>
8 u, [. C1 ]* L  ?) B5 `# N<>  </P>
* n! D3 u/ J8 I  \4 u4 s, [<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
  b2 O+ D& ?" l* v* L0 Y<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
% y7 l5 d% m  i! P<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>! J8 h0 t9 w# ]( l$ a" G& e
<>包含子列和主列上的内容)。 </P>
9 R$ p+ ~. K8 v; [<>  </P>3 m1 p& \- G& ]  g3 k" T) m' g6 a
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>, M8 u% R8 \* ~7 |. o6 t4 w
<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
. p$ v3 T1 K6 R+ c4 \<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>" e$ N9 c" _' Z' u
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
  j: d* E; u" t( y, c) `<>  </P>
+ c1 O% J+ R4 K5 h4 |8 A$ @: {<>  </P>
/ M5 {1 S/ \7 r" ?8 _1 O+ D" s<>void __fastcall TForm1:istView1ColumnClick </P>
8 ?7 ~* V" ?8 x; ]! f: {<P>(TObject *Sender, </P>$ L4 w- |- r* d5 [) y
<P>TListColumn *Column) </P>& y2 R. f' J& p- M8 q
<P>  </P>
+ J/ J" a" I. [1 P0 |% M2 W<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>8 `4 b+ r! j5 N3 Z" k8 ?
<P>点击的列的信息。 </P>. q2 {6 Q$ ]' ?  V
<P>---- 下面先定义变量: </P>
1 j, I$ E/ _* A4 p! b& W<P>  </P>
% l; F* Z# ]$ H<P>int i,m,n,j; </P>& r* n* m& u' k) K+ H
<P>static bool od=true; </P>
5 M5 p0 o9 j, C<P>od=!od; </P>
8 k7 R. c( J7 y<P>  </P>  }& Q- X4 {, O# o! B- c! [% \
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
2 `) \5 g4 D5 z, [7 w) o. X<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
$ _! w4 o; R2 j6 M) W<P>列表框中的总项目数。 </P>
+ J2 h+ R2 r& L* E2 K  S  ]<P>n=Column- &gt;Index; </P>  e- D) l2 ]" B) y" o
<P>m=ListView1- &gt;Items- &gt;Count; </P>* A+ Z" [8 p& N$ k: w4 T8 B
<P>  </P>9 j2 G0 t+ a/ D+ d: Y) s
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
- a9 B8 T8 C1 R( @+ |0 C/ Z<P>ListView1- &gt;Items- &gt;Add(); </P>5 ]! R6 o7 W1 L/ o7 G$ z# v
<P>  </P>3 W: E% S/ j# F+ a8 V5 Y: @/ H8 J
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
3 B' q$ i' e* B# ~. A2 U<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>
* \, I) E5 F$ ^<P>if (n==0) </P>
" u$ k8 x1 L  |1 f<P>{ </P>* Y: v% u2 d5 ?4 z' K  a2 c
<P>for(i=0;i&lt; m-1;i++) </P>
- F/ Q( r# F6 c6 f* P<P>for(j=i+1;j&lt; m;j++) </P>
' I1 a7 z& M& r<P>if(od) </P>5 w. U0 w9 J! b& A
<P>{ </P>, m" B, t: l% ]; ^
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>$ ^% b9 W! W- X9 g
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
. c1 C8 E& D+ F7 L- S  u1 f<P>{ </P>
' o+ B/ s! [+ R6 v* @: D<P>ListView1- &gt;Items- &gt;Item[m]= </P>  I4 t% h$ D: g2 i1 |
<P>ListView1- &gt;Items- &gt;Item; </P>
% C" G4 R& a4 k. W/ Z+ g<P>ListView1- &gt;Items- &gt;Item= </P>
  v6 ~) f. f8 h<P>ListView1- &gt;Items- &gt;Item[j]; </P>' s5 V) f; m( C3 y8 k6 ?; C
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
( R0 W4 O/ C! |$ B0 x( C: O$ y<P>ListView1- &gt;Items- &gt;Item[m]; </P>1 E* Y: r2 x  g+ L' `4 t
<P>} </P>5 M8 N/ Q* Z3 g* F) S( }
<P>} </P>" |7 d3 \$ t/ {
<P>else </P>: q, ]$ f, E5 @! S9 N- e4 b
<P>{ </P>
5 o8 A% s+ v& `0 i# y<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P># B& X) Y. K, y; u% Q
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
3 @1 s' T) n8 a2 O) a; d8 F, X" _<P>{ </P>$ c- j" K. ^/ M! p$ B2 F; O
<P>ListView1- &gt;Items- &gt;Item[m]= </P>0 D1 I, H6 J- _
<P>ListView1- &gt;Items- &gt;Item; </P>) x0 A( s$ O1 h/ {- b9 S& W+ @1 e7 H
<P>ListView1- &gt;Items- &gt;Item= </P>
5 g' o3 v# t$ l. u' t7 x) I<P>ListView1- &gt;Items- &gt;Item[j]; </P>7 X% y. Q+ [% D& K8 L
<P>ListView1- &gt;Items- &gt;Item[j]= </P>" N3 e$ M7 `, ?9 I% Y
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
* v2 H, ~# _- n3 v! `1 C<P>} </P>
2 p9 G7 g4 c8 P! a% r, g) c<P>} </P>6 J5 H. X2 I2 ?5 ?4 H
<P>ListView1- &gt;Items- &gt;Delete(m); </P>+ _8 I# H. \) d2 z& Q. U
<P>return; </P>
+ g1 V, Z/ s- g/ A, ?<P>} </P>  c& a1 {  v' H- h$ J
<P>  </P>4 x& z( c) U! J9 M, ~+ v
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>/ ]+ E  T3 ?" I6 u+ d# S* p
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
* W" Y: B8 b: q4 u  \<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>6 g( D) O. a+ @) v
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
% H: N* d1 T$ r7 O<P>ListView1ColumnClick前面即可。 </P>
) b0 [4 N0 g0 i! q# w<P>#include &lt; vcl/dstring.h &gt; </P>) d! `) J7 h  o9 U
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>& }/ j5 z' A( G
<P>{ </P>1 y% n, `9 n7 i  u9 n  r; I+ [
<P>int l,i; </P>4 z) i. f3 Y' e7 m- j& d. q' X
<P>AnsiString qq(str); </P>
! e+ j5 k5 N2 Q$ O  }/ u* M; v<P>l=qq.Length(); </P>
; s4 u3 z. k* ^9 }; K<P>AnsiString p(str); </P>' Q& F# Z1 ]3 H2 U' ]6 |7 ?
<P>char a[]="\r\n"; </P>
2 D) m! F6 n5 z/ h<P>int j=0,k=0; </P>) h" U# G, `, X  v1 u6 s
<P>for(j=1;j&lt; l;j++) </P>8 q4 F0 @5 M1 t  Z* ]3 ]; X/ V
<P>{ </P>
3 Q7 M4 q. }5 j<P>i=1; </P>
* _5 o5 V0 ^5 B/ m: b7 H. }/ T6 Z<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>( E  w/ _7 v3 Y
<P>{ </P>
* Z( M, S3 f% R  f( g4 U! `<P>p[i++]=qq[j]; </P>6 Q6 D( I0 `! {8 e1 G2 `
<P>j++; </P>
, p9 P6 d6 x2 G1 ?3 k: v<P>} </P>0 L" M5 c* u& _8 \
<P>k++; </P>
3 O9 Y9 X5 j2 }% P5 ]* V# J<P>if((k-1)==n) </P>
7 z" m1 s# D  M$ w# U& Z<P>break; </P>
3 k; r5 i0 R2 `" C" P, r0 l" l! ~<P>} </P>
+ m( `. F* W+ V. `<P>p=NULL; </P>! j/ D3 p& y( f" ]' ~
<P>return (p); </P>
: N( u* t5 c2 ^1 Y8 U5 b<P>} </P>7 G1 F! \% Q( C8 s; X1 B
<P>  </P>( s. ]* ^5 U, O: x& B+ O
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>" Z5 E+ u) ^5 ~4 V* g) ~
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
1 A* r2 o9 h# A, z$ o<P>可完成对此项目的点击排序功能。 </P>% [2 u1 H* p: f
<P>for(i=0;i&lt; m-1;i++) </P>' n  ^1 O0 O4 ?" ?$ s0 B6 o
<P>for(j=i+1;j&lt; m;j++) </P>
, \- p2 Z9 |1 @( J9 A<P>if(od) </P>
, L5 ^' m" m* M9 w% p1 y3 |1 k<P>{ </P>. g3 r+ ~2 l9 B5 p/ j
<P>if(sg(ListView1- &gt;Items- &gt; </P>
2 O- Z+ V. h5 ?# O1 `  h% S- b<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
0 K2 C! q9 j0 ^0 v( \) b, F<P>sg(ListView1- &gt;Items- &gt; </P>5 {; u8 d; [' T/ @9 Y7 [/ S/ V4 ?; M; ]
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
3 K7 l/ _* x# J$ O6 M0 t
. ^1 u- C9 m. K( L; W0 p<P>// ...以下从略 </P>. C/ D( p4 V' r2 R1 o: X8 o2 w* C- `% D
<P>  </P>* H' S1 Y) j+ r' d
<P>最后,删除临时的交换项目。 </P>
! ~: x( e5 q8 E9 x7 x, L) |<P>ListView1- &gt;Items- &gt;Delete(m); </P>* U8 d7 K$ m3 V# ^8 }
<P>  </P>! r& Q$ L  T+ z8 t$ {
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>
) \% X# U" c" J/ u: b<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>; E: \1 t  {- e" e$ _1 ?5 B6 c
<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-6-14 10:52 , Processed in 0.514978 second(s), 52 queries .

回顶部