QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<>  </P>
1 x* p; `0 d! d5 ]<>  </P>* O5 R, h/ l- p  f/ M) a$ p
<>天津大学电子与信息工程学院 </P>. V3 {. X" z6 d% a3 o! }( d5 K
<>宋天宁 </P>
8 Y+ }2 C' ~5 I$ n& Z# F2 D<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>/ ^/ X0 m. C6 V6 Q$ H& k
<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
/ P% R" d% e% T! ^; C# [! @<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>8 h9 P2 c/ \4 d* I3 \; {
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>
6 J% i& Y' `2 L7 f* N<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>
$ e& |6 O, V! t& _6 j<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>6 r4 U3 }# A$ g" B/ p
<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>
9 Y5 ^/ [4 R2 g* d<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>
0 v  T" q; f1 \( p3 g/ _. y5 _<>写自己的代码以完成这一功能。 </P>' W9 _* q6 u& p
<>  </P>
( l# H$ w. }; V( O- Q# T<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>! q; o" W+ M3 ]1 E, K
<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>0 J# b7 v4 {  X/ q9 E
<>内容以升序排列。 </P>% X+ c* q5 p% X' ?  X
<>  </P>
+ L# v; y+ M' [9 N5 A. f2 Z& {<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>& [! L6 ^, Y% B5 U3 T
<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>: y4 I' c) j  b$ e
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
6 Q* i% i3 K; ?, w' l4 _<>包含子列和主列上的内容)。 </P>+ Z0 D" u# i/ ^' @: h; C
<>  </P>
) S5 e4 g1 U$ u0 y" ~# m) A<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
' ]0 r3 j. ~2 f7 a/ S3 i0 _<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>
3 ^0 t; Y7 w: Y2 V, r# `<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
1 P$ I/ U9 v9 l8 l) r7 d<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
4 p: s" @+ O7 f4 f. Z<>  </P>
: D) ]  I  ?9 v5 R) j5 Q4 o" O<>  </P>: V+ E) h2 S9 R# z+ `- E- m% }
<>void __fastcall TForm1:istView1ColumnClick </P>! t1 H: M( \" l
<P>(TObject *Sender, </P>
; N1 U/ u8 k" `2 F<P>TListColumn *Column) </P>
0 h$ a' ^0 l' y9 H8 _* ]  r<P>  </P>
- C/ w/ `3 {( i* ^  M; J; G7 Y$ V<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>! h- T  X% J+ K' z
<P>点击的列的信息。 </P>6 l6 a, t. J( j. {1 x+ P
<P>---- 下面先定义变量: </P>
& {. h% \$ a7 @+ \<P>  </P>
+ Y% R( [) ]7 B6 C<P>int i,m,n,j; </P>6 n+ K) I5 N3 a$ w9 c. u4 _
<P>static bool od=true; </P>
/ q" p, |8 x0 x<P>od=!od; </P>
  P. Y& W6 H7 N8 P<P>  </P>
: p3 f* h: D+ X2 F# q<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
) N2 B: @6 s& `* s<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>
& O, h. n% I& K# `* i! H3 c<P>列表框中的总项目数。 </P>
6 N$ \5 x. i2 `% A+ w" W<P>n=Column- &gt;Index; </P>
3 _& ~# t9 }! j* a8 I<P>m=ListView1- &gt;Items- &gt;Count; </P>' Y; u. z8 D% E+ ]/ Q9 A9 d
<P>  </P>. G+ }3 h( ?$ i  @. N
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>1 @4 p9 L3 k0 H8 p- d$ A  e
<P>ListView1- &gt;Items- &gt;Add(); </P>5 }% T& ?; q2 Q/ ~" z' {6 n1 x
<P>  </P>
* G" \5 B0 ?; o/ Y; G; a<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
; I9 f) {* ~3 M) t' k<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>' Z0 R; ~1 @) w8 Q. X4 u  ]
<P>if (n==0) </P>
  g  [) a* K+ O0 K<P>{ </P>" [0 H, w- X8 D# O6 l+ N# j6 J: C
<P>for(i=0;i&lt; m-1;i++) </P>8 m, ?3 I" z: H9 L. G
<P>for(j=i+1;j&lt; m;j++) </P>
# p/ c' c# Q5 @; y<P>if(od) </P>7 p( o7 }$ B4 I- x; L3 g; I
<P>{ </P>; z, u( O6 J* c) X6 z
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>9 Z/ }% h9 P" V. z% ?# F0 ^7 ?9 m
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
, j9 @- D- V0 ]4 d0 e# v. \, z<P>{ </P>% T3 I& X& \* a/ q" l& o- H
<P>ListView1- &gt;Items- &gt;Item[m]= </P>. c( Y! P% i, u/ C( Z! O2 a( |
<P>ListView1- &gt;Items- &gt;Item; </P>8 R6 ?8 C( t# y7 t# Z& e7 d3 B5 S
<P>ListView1- &gt;Items- &gt;Item= </P>
( \# W- N7 W! s<P>ListView1- &gt;Items- &gt;Item[j]; </P>: ?" {' _/ u; T/ A: @5 i! b
<P>ListView1- &gt;Items- &gt;Item[j]= </P># ]' E6 Q! D/ V- L3 A% B4 O% b) R* B3 `
<P>ListView1- &gt;Items- &gt;Item[m]; </P>
5 a6 w, b0 ]) S3 b<P>} </P>
0 p! }( t* \) _<P>} </P>) I( \* o+ \6 n" Z4 a
<P>else </P>
. g* A& r7 [0 i/ M: }3 c<P>{ </P>- h4 V8 q) i1 }, K; B" ^1 [
<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>$ A! a% N7 {3 g4 {+ a. Z3 \
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
( Y  ~2 Q2 ]; @$ S$ r- I8 p<P>{ </P>) C& a6 s3 V; d3 K1 W; }/ }/ B
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
. A% v6 a8 B) o3 b) |% B3 Q" T3 }<P>ListView1- &gt;Items- &gt;Item; </P>: {% o7 U! Z; O7 c3 F9 ^
<P>ListView1- &gt;Items- &gt;Item= </P>( E# h" H+ ], R5 K1 `
<P>ListView1- &gt;Items- &gt;Item[j]; </P>
( {9 V. L" t7 K% Q; S! q+ L<P>ListView1- &gt;Items- &gt;Item[j]= </P>
$ B# V& g; P2 O* O# r; @" d<P>ListView1- &gt;Items- &gt;Item[m]; </P>
  x: k) p$ w5 Z, Y$ m8 b  a<P>} </P>& {; d9 W/ z- S5 C, X- R
<P>} </P>
" M/ \) {, U8 D+ _4 d( N<P>ListView1- &gt;Items- &gt;Delete(m); </P>
; v% g9 V( z: D3 N4 A# X<P>return; </P>
& K: W/ p5 w3 Q6 E) E4 X* I<P>} </P>& j) f4 {3 S' E" }
<P>  </P>% z. f& N1 |, L+ Z# _. r1 E8 }  V- z3 w
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
: H7 u: a  P$ Q3 F, G2 x- _% {<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>8 v( u$ Z& _3 o8 I" p9 v+ j$ \
<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
2 W2 ~8 Z8 W$ ]& |% e<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>( k6 V3 N9 A. u) e# s
<P>ListView1ColumnClick前面即可。 </P>/ Y3 h! p, u& M9 c3 [6 ^1 Y
<P>#include &lt; vcl/dstring.h &gt; </P>7 W  y5 d9 b6 q8 z/ C7 O
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>7 c4 c9 w( L' f6 C
<P>{ </P>: l: b6 C9 U! ~# o, W
<P>int l,i; </P>6 G; B  J# M* ^1 e; b
<P>AnsiString qq(str); </P>1 Y3 ~, M, r0 w: M$ F- @
<P>l=qq.Length(); </P>: @% m  f) r* N5 v2 l- U7 @
<P>AnsiString p(str); </P>
( f$ Z  t# R  e. t* W+ b<P>char a[]="\r\n"; </P>
: A0 v/ g7 a$ J( C# \<P>int j=0,k=0; </P>( z; S0 f* ]7 }9 O$ s" G* b0 K
<P>for(j=1;j&lt; l;j++) </P>6 j+ _+ u) i/ ^) ^9 @/ Y8 D
<P>{ </P>$ r: l) \9 H( G+ w  C
<P>i=1; </P>
0 ^* l' n1 D0 k<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>
( ]9 q1 j0 D( c2 Y3 U<P>{ </P>; R1 Q" u" e0 Y3 y
<P>p[i++]=qq[j]; </P>5 U( u* G4 O* m7 C+ K$ U: G
<P>j++; </P>
, s3 n  W- Y5 \9 m, p<P>} </P>+ I% V5 @+ |( |9 s; Q& m2 c
<P>k++; </P>1 ^2 D9 l% H9 l& s
<P>if((k-1)==n) </P>
% ?+ V& ~1 r3 E0 Y3 l8 h) n& |% |<P>break; </P>7 |! |$ `- p2 Q% ?6 J, V8 {9 s5 m1 F$ A0 P
<P>} </P>
1 J/ F% B  U* Q( C<P>p=NULL; </P>; r' {0 i0 ?2 d
<P>return (p); </P>
7 `3 |. S+ Q& t; X; |; e& F<P>} </P>
6 W8 C+ l$ T, t- t$ c- ?8 j; O) t<P>  </P>6 d' k, c1 y; \8 p
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
" E" s1 L' S) w( E<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
8 {; q2 k7 W/ M) R, H2 e3 b<P>可完成对此项目的点击排序功能。 </P>2 K" t/ C" F/ M7 [. q6 H6 Y8 X' f
<P>for(i=0;i&lt; m-1;i++) </P>
- N. z! h' c0 W2 s$ \) I1 v* h<P>for(j=i+1;j&lt; m;j++) </P>
; ~: Z6 c& T' y/ \! `+ |% q<P>if(od) </P>
5 j5 s2 ]" X. G& Y$ z. W8 [2 b<P>{ </P>
8 E  j4 T0 G- A$ p<P>if(sg(ListView1- &gt;Items- &gt; </P># q* i) [: b9 b# ]
<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
1 Q  s$ o( u0 z1 D; c- l/ F<P>sg(ListView1- &gt;Items- &gt; </P>
1 {6 X  g' h. E$ N8 s) R# z<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>9 C* D& c* |) |3 w% d9 V3 _
  A3 z- c5 b' C& ?- n: T+ H: e
<P>// ...以下从略 </P>5 t$ o& y8 O9 r( B- m+ X
<P>  </P>
# f7 F7 s+ m$ n% e7 \7 l7 p6 e# Y5 l<P>最后,删除临时的交换项目。 </P>9 L) }3 Z: y! p
<P>ListView1- &gt;Items- &gt;Delete(m); </P>
% s$ u9 M2 |9 T<P>  </P>
& T) u& T  @9 |; o<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>" j( D7 L3 m& j- d! E
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
: k7 c& r, d9 t4 M<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-21 07:36 , Processed in 0.445759 second(s), 52 queries .

回顶部