QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
5 k0 w1 d0 h! f: _* B( q; j6 M; P3 i) |<>  </P>( x8 Q2 \( L3 a% K6 a& Q- ]
<>天津大学电子与信息工程学院 </P>4 J, s+ U- y4 Z/ D0 x
<>宋天宁 </P>
7 K) u/ ]8 j: {1 }, c2 }5 O<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>4 T4 i4 V  l8 p; j! u. e
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>$ a- [  t: @! J3 X7 _# g0 U: c
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>& C, q+ v% M, q6 M$ q
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>" a8 t7 n' v: Q- X: A+ U+ d
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>/ l4 r7 J8 n" w( r" k  }0 p
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
' \3 \4 B/ e4 J<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
% }$ q* S5 I! [! J<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
& W" r3 B2 v% l* {: [7 I! D<>写自己的代码以完成这一功能。 </P>$ J5 _/ u: H1 S
<>  </P>2 t$ D  y8 G- o2 L) ?4 O
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>$ z; W5 p$ F& R7 a  n
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
. w' Y; W: w2 ^+ B5 A* v3 N<>内容以升序排列。 </P>9 `2 H3 ?$ ~9 T
<>  </P>
# _* R( F9 h) `' m3 w7 C# k<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
" [- e6 j# {' W8 M& Q( z<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
* m; L" ?6 l" z( y* O; m7 m! x<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
% _+ ~3 A8 m3 @<>包含子列和主列上的内容)。 </P>, }# _; _5 A8 t# Q/ [) `
<>  </P># E) F. v3 L# D+ m6 A( s
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
* v7 {- Y( w; ~- k, |8 k9 T; ?% P<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>+ e9 `, }- s9 u7 D" p: Q
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>. t/ ]8 Y) Q0 a/ V2 v+ v% q
<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
* U; F+ x; U/ ]& s# S<>  </P>6 U) M9 l- N& _3 D( ]5 }! s& n& ?" |
<>  </P>
7 k. l7 i9 e, V4 }5 m9 _( Z1 `<>void __fastcall TForm1:istView1ColumnClick </P>
- u; }$ n, }  O. _6 w1 u) w8 m& ~<P>(TObject *Sender, </P>) V9 c& I9 y+ F! K3 Y* l
<P>TListColumn *Column) </P>
$ D8 C9 T4 Q0 |' [<P>  </P>
) I5 L3 h) r8 W6 Q, ?<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
' J* g. \) |4 \+ z<P>点击的列的信息。 </P>$ v5 o8 M& P+ o6 P# T$ G
<P>---- 下面先定义变量: </P>+ E. g$ Z+ Y" z! h" I5 Z
<P>  </P>
6 D8 t& w% b# w<P>int i,m,n,j; </P>: _2 P  X" g% s" T5 a  d' d; E6 k  {
<P>static bool od=true; </P>* s/ n  K8 w0 A" z5 u
<P>od=!od; </P>& c3 n- W! ?8 C% W/ X! |
<P>  </P>9 q/ y3 x) \/ A, k  [  ~2 ]  L' X
<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>; W0 T3 K% t$ x5 z3 I- J
<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>9 b1 L( ^% i3 s% f2 o
<P>列表框中的总项目数。 </P>
& Q5 L3 I2 F% n  w5 |( h/ G; a<P>n=Column- &gt;Index; </P>
' z2 t- w2 D0 P& I9 J6 v<P>m=ListView1- &gt;Items- &gt;Count; </P>) y# ^" A. X+ c+ P- D
<P>  </P>
2 F9 ~9 I+ x8 o<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
! ~' R3 p% ~/ M<P>ListView1- &gt;Items- &gt;Add(); </P>
4 P3 \. P: a+ [( a; i0 G<P>  </P>
2 U& ~6 W- k& g. f5 g<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
7 X! U. T8 a7 V  z<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>2 G; z& H1 {3 d" q6 B" X
<P>if (n==0) </P>) i. n7 @  M; v8 ~
<P>{ </P>
) Y* L1 R, D& c% j" p4 h2 T/ ^<P>for(i=0;i&lt; m-1;i++) </P>
6 D; J: s. Q7 t<P>for(j=i+1;j&lt; m;j++) </P>
7 R  {( n! Q8 n8 S. g<P>if(od) </P>; Y& d4 ]' y1 Q, i- |5 n5 E* q% P
<P>{ </P>
6 G9 |" }( y  Z<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P># r% ]+ y& j' U, @5 U1 J
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>; j, h7 H8 w* f) o* @
<P>{ </P>1 T+ f# U- ^" q( i- m
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
7 ]+ ^4 O/ _; [- ~- I<P>ListView1- &gt;Items- &gt;Item; </P>' D: a( ]! e6 q  K7 t7 \1 h. q& c
<P>ListView1- &gt;Items- &gt;Item= </P>. J& ~( ?9 h& g
<P>ListView1- &gt;Items- &gt;Item[j]; </P>" R7 G. U( d4 p1 x
<P>ListView1- &gt;Items- &gt;Item[j]= </P>+ E& W( a$ |  l6 a9 O
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
" U2 m! F1 P. n7 |4 C8 r9 {<P>} </P>
, J5 ]8 g* j" ^' w6 E<P>} </P>+ g2 f. u9 \5 Z7 j% S, e; M8 A
<P>else </P>/ n8 L0 ^/ q: Y' w- H) H4 c
<P>{ </P>4 f' {: U" k& r0 A
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>
8 J' Y6 H3 L2 r& Y4 D* }<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
2 {1 k1 A& M1 x$ S* v<P>{ </P>
. F% y9 U' h# w* E# V<P>ListView1- &gt;Items- &gt;Item[m]= </P>
9 k4 e/ C+ G$ }4 Q<P>ListView1- &gt;Items- &gt;Item; </P>
* T& a* P5 S1 t7 w) Z<P>ListView1- &gt;Items- &gt;Item= </P>
* e# c8 I1 W1 J<P>ListView1- &gt;Items- &gt;Item[j]; </P>. u. J$ I$ B7 N* X. Y$ t% r2 ^* r
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
6 ]5 \+ K" R! X/ V: }$ Y( P<P>ListView1- &gt;Items- &gt;Item[m]; </P>
/ k7 n! ]: i5 b# I7 [5 d<P>} </P>
' g2 \, \/ }/ V<P>} </P>
* m3 @5 @0 S' L: y8 E6 g<P>ListView1- &gt;Items- &gt;Delete(m); </P># p0 i$ r, S& _3 X/ ]
<P>return; </P>
. K/ ?. q0 Z3 K8 c1 o<P>} </P>9 W1 ?9 ~0 ~5 D4 R, ?3 _
<P>  </P>
1 u1 \$ l6 ~! r0 R: O<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
2 T: Y+ p) w/ F! u* A& }' k. n2 o7 z<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>! F' M% T$ D- u0 F; ?
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>! ?' k4 o( \+ y; C+ X6 J
<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
" Z1 b5 O% P  S% ^% P6 o/ D<P>ListView1ColumnClick前面即可。 </P>
/ e) R  K! D. `& C5 c4 U" L" V4 V<P>#include &lt; vcl/dstring.h &gt; </P>% D: P: A6 \4 `
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>0 k5 A3 p# n9 j! k- ?3 n6 H) s
<P>{ </P>! k0 y# w5 e5 V
<P>int l,i; </P>) ~, \" e) D/ [
<P>AnsiString qq(str); </P>
; X9 K5 p9 \6 e- ]! O4 C<P>l=qq.Length(); </P>0 N/ E6 L  S/ g' Z( T. N5 L3 J
<P>AnsiString p(str); </P>) \; m4 j: }8 d0 T7 [* I
<P>char a[]="\r\n"; </P>
& @; i/ b, o: y+ ^<P>int j=0,k=0; </P>8 R# E0 `  j) i6 s  \
<P>for(j=1;j&lt; l;j++) </P>  q% t# [' T$ g- M% b
<P>{ </P>5 |- M) R6 k% a2 F
<P>i=1; </P>
$ Y6 _. l) w. P$ d6 \6 U% B<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>+ T! w8 _! t! S; |
<P>{ </P>, G( Q2 p; |9 j3 F- D
<P>p[i++]=qq[j]; </P>" [) w4 J# B9 z9 E
<P>j++; </P>  ~+ t7 @$ ?8 D* C! z9 Y
<P>} </P>4 _3 X2 V& ]! \! z. V
<P>k++; </P>
! ^5 S( D" I) p<P>if((k-1)==n) </P>
& U& ]8 ~5 ?9 J4 w9 D<P>break; </P>
( m4 H0 @4 U5 Z3 C' u, r$ O<P>} </P>% f! L; f. X1 [
<P>p=NULL; </P>
; a: I" d" B, s8 i# b0 }! H! w8 R<P>return (p); </P>
6 \6 D' P! g" A8 k<P>} </P>7 x; N$ [, q0 y' M2 u- p/ q* O! g
<P>  </P>" i6 n  q1 Y* s/ ]: X: O
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>* ?" F3 y0 f$ \* M
<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
- u7 M# p! _' {5 u2 T<P>可完成对此项目的点击排序功能。 </P>
" `, [+ Z: m3 W4 a. ]1 \/ ~<P>for(i=0;i&lt; m-1;i++) </P>2 P! s( v1 |( J! x: T9 k& O
<P>for(j=i+1;j&lt; m;j++) </P>7 b- ?, J# {2 c# U5 R
<P>if(od) </P>
4 J0 n) d+ A3 B" Z0 t! l! F+ }<P>{ </P>
& M- N5 m* H) W% W+ |7 a<P>if(sg(ListView1- &gt;Items- &gt; </P>$ G4 R+ D! M' d' f2 q% i% x
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
2 D3 a1 q5 s) M! R$ [1 R# J9 v<P>sg(ListView1- &gt;Items- &gt; </P>
; i9 Y& |3 g! N8 [7 A<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
9 q% p* I6 F& j4 s& |1 D. ~  n' c; m2 d' @2 H& a( Z/ O/ |/ B
<P>// ...以下从略 </P>
6 J1 J1 X. r4 a& _3 T. @) W' S<P>  </P>
. E, Z% M7 G: w5 x0 R<P>最后,删除临时的交换项目。 </P>
3 R* X/ W; I8 L5 u2 P: o- y<P>ListView1- &gt;Items- &gt;Delete(m); </P>& e% b' I# p- z% g2 x
<P>  </P>) K4 o5 @3 o+ b7 G! j
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>' v/ [0 b5 b1 f) v' I
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
% s3 i3 K8 X* i+ O7 D1 M2 o<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-10-17 07:43 , Processed in 1.671265 second(s), 52 queries .

回顶部