QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
! L; ~; [: l5 @8 U<>  </P># ]4 l- x+ i& c& Y
<>天津大学电子与信息工程学院 </P>
! B9 ~0 I  P: U* x) D<>宋天宁 </P>
- g- g/ V9 l: q  m$ L$ P<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>1 V! L+ v5 y6 ?
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>9 }- q0 F, v. t6 n  R3 z
<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>
8 x1 X, l" B" h# v7 T- }<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
4 Q9 u( [2 s& E7 G" {7 k<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
  j4 B7 U* A3 l. [<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>! W6 D. S( n$ i, z1 o; g9 @
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>: ]) @) y# v: Y
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>& y4 t4 a9 x! j! `- T7 K& s! z
<>写自己的代码以完成这一功能。 </P>
: S" n; C# _$ ]/ t! {<>  </P>& y! \( i: Y# D  {4 Y  z. B* @
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>9 [' y" E6 ]# m  J& G
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>1 z# K# |! v" C' l0 n
<>内容以升序排列。 </P>
! F. e3 c* d" H7 s7 ^8 M<>  </P>
. R# Z" s7 f) k& A! t<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>4 v- S1 r  s8 o0 _+ ^( n
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>
) n4 B" f. ?3 A1 `3 U* V<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
3 Q) K- M# k8 T<>包含子列和主列上的内容)。 </P>0 U% k; V+ p$ R# P- W# P- m
<>  </P>3 Z) N) _% J. _) B
<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
+ ]4 M+ k9 ?6 s. C/ d<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
: e- A9 H" y; s  ]; O1 X1 h<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
# {% ~4 p: L3 |% ?; G<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
) ~# r7 ?; ]0 Y; \# \- V( q% a5 R<>  </P>, o; m, z/ |, z% i  h8 y7 `3 k
<>  </P>6 V: B3 {$ h3 K" H7 {
<>void __fastcall TForm1:istView1ColumnClick </P>
0 ^8 J' O( G" z) X; A+ S<P>(TObject *Sender, </P>$ H  A3 r9 u. E) h& H5 |
<P>TListColumn *Column) </P>
( A- W. a! p' j& \<P>  </P>! n+ M/ u. X: f3 U7 w0 [! W
<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
3 p; |5 `7 C+ E& [6 l<P>点击的列的信息。 </P>
0 O4 w, @4 Q2 F" Z; b<P>---- 下面先定义变量: </P>* w: Y& N) d4 |6 X7 @: I# H0 @6 {
<P>  </P>9 P+ Z/ p! o7 D1 j* b
<P>int i,m,n,j; </P>
& Q4 Y4 l; i1 W2 }<P>static bool od=true; </P>
' F& A, |. z$ ~- u- l* v<P>od=!od; </P>
" j# F4 a) f5 w# _9 D8 l3 E<P>  </P>
; B1 k; q. h2 `& O<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
6 \' a# q2 Y5 \  |* w# p<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>4 [. e9 d6 x* y- G% g7 T( o& _
<P>列表框中的总项目数。 </P>
+ F+ T- b; _& h" O' H. A<P>n=Column- &gt;Index; </P>& x- O# ?& h1 P' J4 y
<P>m=ListView1- &gt;Items- &gt;Count; </P>
: }! I8 y. R4 ?<P>  </P>
3 x: ?* t( i" g9 C<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>
% @9 w( V4 m# J<P>ListView1- &gt;Items- &gt;Add(); </P>
0 n3 R4 ^& D7 G# a% B) h$ x<P>  </P>
8 \+ R9 h, I( W<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>) k1 J: y. s2 w# F  b
<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>5 h, n; v: @- W
<P>if (n==0) </P>
  J; m# L7 X3 f% e& ]0 _1 e* G, f/ D<P>{ </P>1 ~1 ]3 j: {& `
<P>for(i=0;i&lt; m-1;i++) </P>
7 }# |0 c5 Z2 f, @<P>for(j=i+1;j&lt; m;j++) </P>
% x/ H; Y4 J9 u9 F<P>if(od) </P>. R' d3 N9 y) ]
<P>{ </P>5 k9 d9 u& [  C, w" {4 M2 h
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>9 S8 I- z. o* Y$ Y' n
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>5 @! m+ Q& d: }5 Q( e# ?3 \! P
<P>{ </P>
' E- l6 U. z: _5 P<P>ListView1- &gt;Items- &gt;Item[m]= </P>
* s) g- A. n  I* l<P>ListView1- &gt;Items- &gt;Item; </P>
3 r" x) u# ]3 T<P>ListView1- &gt;Items- &gt;Item= </P>
) Q3 \2 ?7 j: s2 m" f+ J# b8 L# r7 D<P>ListView1- &gt;Items- &gt;Item[j]; </P>
& C. a. Y! Y0 S. M<P>ListView1- &gt;Items- &gt;Item[j]= </P>7 }- d5 r" v" F
<P>ListView1- &gt;Items- &gt;Item[m]; </P>+ Z, d0 i' ]) e  v- X
<P>} </P>
2 Z4 U, A) M/ k$ M<P>} </P>
/ s2 L, @" t9 M5 E/ h( ]( z; B$ F5 w<P>else </P>
% S% {& S+ k, Z( o- m<P>{ </P>7 C3 X4 P3 F" d$ ?
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>& e- N9 I4 K# O9 ~- B% ~6 \
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
8 c/ H$ A+ v, R; p6 S<P>{ </P>5 S: y- u9 z/ f: @  W8 F* j
<P>ListView1- &gt;Items- &gt;Item[m]= </P>, t" Q  U0 _, ^$ w" J; y* O2 i
<P>ListView1- &gt;Items- &gt;Item; </P>
, p& K8 G* d; j: L3 Z, E  u+ W<P>ListView1- &gt;Items- &gt;Item= </P>- n4 p! y1 y# j
<P>ListView1- &gt;Items- &gt;Item[j]; </P>' P- {- ]3 R# V$ T( `  X
<P>ListView1- &gt;Items- &gt;Item[j]= </P>
' c* A1 i( w  I1 e% h$ L<P>ListView1- &gt;Items- &gt;Item[m]; </P>1 ^' v) ]! h6 [3 \/ J* K! [
<P>} </P>5 F+ N1 q% a; P
<P>} </P>
! N; g: n9 x3 q9 K1 g<P>ListView1- &gt;Items- &gt;Delete(m); </P>
/ }+ ?+ k) S  ?& N" U<P>return; </P>! ]+ X$ F: |: J  @$ N
<P>} </P>4 V, c' P# V% _- ^$ R/ I
<P>  </P>8 @5 U( h5 @$ b+ x" d4 m  C- R
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>( p# W& H' C; ]) c" p8 O) I
<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
4 E5 W/ s- L' w0 Y1 F<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
2 G5 w# [6 p1 ]( v/ D<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>
! j6 s; Q. ^( V. {8 z+ s<P>ListView1ColumnClick前面即可。 </P>
0 m& i( L/ ~) _7 A, e" ]) N<P>#include &lt; vcl/dstring.h &gt; </P># [  {% N/ f; ?/ y+ ^( ^' S
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>$ W. R7 l6 [. R/ T0 `" Q  t
<P>{ </P>' u( w7 z5 \! k& q# Q8 D: C
<P>int l,i; </P>
' {3 p5 C: h/ q7 ~7 H<P>AnsiString qq(str); </P>
, s5 }6 R2 E  o6 b  T+ R/ ~9 A<P>l=qq.Length(); </P># ?6 q* i  E  [" Z) g9 `0 j
<P>AnsiString p(str); </P>
) R, M$ h, L5 C( T# j+ P' Y<P>char a[]="\r\n"; </P>7 o# B9 u% _, o7 c( F/ m# m. c8 j
<P>int j=0,k=0; </P>
) K9 R3 d% B- n$ O<P>for(j=1;j&lt; l;j++) </P>
9 |/ p5 [* U" J. R/ J# ~2 U& M<P>{ </P>
2 a" [6 H  L6 p<P>i=1; </P>
" z& p& P; E2 ^( X8 ?% M<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>2 W3 c, w* ]$ f7 l- r- k/ e
<P>{ </P>
. k- v" S: _2 l& v5 _6 {( m5 m<P>p[i++]=qq[j]; </P>, y' n% y- p$ a
<P>j++; </P>
& e; f; i, d+ n( C( c1 s<P>} </P>
2 a. X$ J. O& i4 O4 i! }, s* a! h<P>k++; </P>
0 c" h, ]7 R( m0 n8 {; J<P>if((k-1)==n) </P>
8 F% T2 x$ ~; e1 _! a<P>break; </P>
: i& H0 t  D9 |<P>} </P>; ~( E5 a/ T5 S1 ?' U
<P>p=NULL; </P>
9 ]. N7 a' v6 W  D& J/ M<P>return (p); </P>
/ r+ R8 k. ?, Z<P>} </P>4 h2 j5 F" \% J8 l/ c2 W
<P>  </P>
8 V# \6 N: H/ t  U) h6 p5 D! c<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
: Z: ^5 }$ h# a; Q# w8 ^, o& G# Z. @<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>' `- h( ~3 U+ ]  L* `
<P>可完成对此项目的点击排序功能。 </P>
& @' m6 ]% l/ j& s; r  w3 K0 x) [: a<P>for(i=0;i&lt; m-1;i++) </P>8 N2 |) O' h+ j+ j/ k. }4 q
<P>for(j=i+1;j&lt; m;j++) </P>+ K- l1 q4 ]3 I" N% i4 h
<P>if(od) </P>
1 v; X2 d9 X  d: d0 n* G: S2 ]# A<P>{ </P>: e( `, P- o0 h5 `; U) y+ @$ }
<P>if(sg(ListView1- &gt;Items- &gt; </P>9 c$ d% p7 M7 J: Y9 i
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
! Q2 f! U5 D/ }$ a3 A, j<P>sg(ListView1- &gt;Items- &gt; </P>% l, v- w) j' r. q% E8 W
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>. n/ o5 m! O! e# ^: ^
, ~5 @+ ~1 O' v9 l8 x
<P>// ...以下从略 </P>: _8 L$ k; Q1 B
<P>  </P>
8 p2 C. Q6 \0 w0 C9 ]: t<P>最后,删除临时的交换项目。 </P>. Z7 M( q# ]  h% D  t
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
! [1 r2 _! y; B( e<P>  </P>
5 `" D5 [3 h9 a<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>2 T5 p" G$ }6 ?! O$ X
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>  T3 \# H+ I3 O4 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 08:00 , Processed in 0.330948 second(s), 52 queries .

回顶部