QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 12:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>7 D; R( E! D  a' }
<>  </P>
- U" w  W+ n: C2 e% C' _<>天津大学电子与信息工程学院 </P>6 e5 s) v3 c. A" c8 ~
<>宋天宁 </P>+ z: U/ A- s1 ?" U0 J
<>---- 列表框控件在应用程序中的使用率很高,在Windows中经常见到, </P>
2 [3 q- s4 b0 b; _7 y<>它有四种常见的式样,分别具有显示大图标,小目标,含有图标的多列列表,含 </P>
; `" r3 p* ^$ r<>有列标头的列表。我们也经常见到一些扩展功能,例如我们在资源管理器中的文 </P>- |6 Y' J! M$ ?9 i9 G% j$ R
<>件列表框中,在选用详细资料察看时,用鼠标单击列标头,如大小,则所列文件 </P>; t" c4 G1 t3 D, E
<>按大小排序;单机日期,则按文件日期进行排序.这一功能增强了应用程序的可用 </P>0 j, Z9 y0 K$ V" s
<>性,使操作更直观、方便。笔者在以Borland C++Builder 3.0(以下简称BCB)作 </P>
  K( ?7 I3 p* w1 M<>为开发平台实现这一功能时发现,仅通过设定列表框控件的属性值的方法,只能 </P>/ }( g$ A4 h' p. M, y. k
<>根据项目的首列加以排序,不能根据子项目(SubItems)排序。因此,我们需要编 </P>5 ^( T6 m7 ~6 q
<>写自己的代码以完成这一功能。 </P>
) J! r; H9 s$ g7 X3 }5 V" K<>  </P>2 ]4 A, u, N6 m0 k5 }# V
<>---- 以下描述如何在BCB开发平台上为列表框添加列标头点击排序功能,当我们 </P>
/ t* W8 ~2 I/ W! I- }) `<>点击的次数为奇数时,所列内容以降序排列;当我们点击的次数为偶数时,所列 </P>
& h0 a4 F$ ~7 Q" v$ J<>内容以升序排列。 </P>" z3 m! b+ Q$ _
<>  </P>
+ v7 t8 [- E  y+ ~5 d<>---- 首先将一个列表框控件安放在Form上,并将其名称设为ListView1。然后在 </P>
1 v6 `; n3 z- ^( y' D0 Q1 n# K<>其中添加若干项目作为试验对象。方法为:用鼠标右键单击控件,在弹出的对话 </P>/ o) R; }3 J$ @) A* U; G7 o  F
<>框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目( </P>
7 {1 o( {3 Y: f+ u( F<>包含子列和主列上的内容)。 </P>
7 j* Q7 k; O" W: X4 U2 Z. H0 j6 ]<>  </P>
! Q$ g4 D! ]4 t" f<>---- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值 </P>
+ P0 ^; i% s! J( R<>,将ViewStyle设置为vsReport。另外,还必须将SortType设置为None,以使我 </P>: f' e$ o8 `; ?! V% G9 I$ ]
<>们的排序程序起作用。这样,程序的外观已经符合需要,下面应该增加排序功能 </P>
6 g0 @7 L3 A0 ?& k/ F) n* g5 ?8 H$ o0 W<>的代码了。为此需要添加类的方法到源代码中。添加位置为: </P>
5 K6 w; O, p( [1 p! B5 x<>  </P>
7 |7 a: x" o5 k% F1 [6 B/ a<>  </P>2 w( F7 w4 e1 T0 X, Z
<>void __fastcall TForm1:istView1ColumnClick </P>7 m+ g. m5 B8 W
<P>(TObject *Sender, </P>3 I; u0 |, J4 ~* \1 P* k& W
<P>TListColumn *Column) </P>0 x* }8 t6 f# u( A+ ^' W7 T
<P>  </P>
6 S! d- E3 J2 M% G- ~. d2 Y<P>---- 在该方法的传递参数中,指向TListColumn类型的指针Column中含有用户所 </P>
5 X: a+ ~6 b9 a+ A. T<P>点击的列的信息。 </P>2 h% h$ ~$ i9 l: Z- N+ n
<P>---- 下面先定义变量: </P>
7 L1 P& _2 f5 X% _) @' l6 S& e<P>  </P>
, y( T6 e( G9 X/ D$ Z<P>int i,m,n,j; </P>( Q! R/ D7 @, k: h$ Z$ l+ S
<P>static bool od=true; </P>
" t# F: m. k" A9 l1 b<P>od=!od; </P>; c- w  V, C) y+ H; ^: @4 S* m; u
<P>  </P>
+ R/ X  |8 c5 l. x" y' w8 _& P<P>---- od代表用户点击的次数,奇数时为true,偶数时为false。注意此处od的存 </P>
: f: p" ~) A, E+ p<P>储类型设定为static,可以保证其数值的连续性。用n记录用户点击的列号,m记录 </P>+ h- j: ?7 D" G6 g
<P>列表框中的总项目数。 </P>& B6 ]$ N% n/ g- U* \5 D
<P>n=Column- &gt;Index; </P>
; g- b2 E3 j" x& c<P>m=ListView1- &gt;Items- &gt;Count; </P>
0 v4 \0 G% y5 N+ ]: [<P>  </P>6 P" A/ h/ J! I. D9 l% A* ~! ~+ K
<P>---- 在列表框中临时添加一个项目作为排序中交换用的临时空间。 </P>5 q& F" c$ }2 x
<P>ListView1- &gt;Items- &gt;Add(); </P>, D2 t: X1 U5 I4 w" |
<P>  </P>% @6 [: [6 C' T& U
<P>---- 当用户点击第一列列标头时,排序按ListView1- &gt;Items- &gt;Item- </P>
$ T9 {* h/ N" p. q' }% ]<P>&gt;Caption进行,与其它列不同,所以要单独进行排序。 </P>  Z" C6 E) b4 e# u( G4 u0 X& n
<P>if (n==0) </P>1 R. |: F: W# r
<P>{ </P>
: V- T6 ^) a$ Z3 K( p$ |0 ^<P>for(i=0;i&lt; m-1;i++) </P>
# `  o1 N  Z) Z& z<P>for(j=i+1;j&lt; m;j++) </P>
7 t; _5 }4 b# |0 c4 O" b<P>if(od) </P>
' n# A" B/ ?( h+ P! p<P>{ </P>
: [; r0 i$ W* B; |<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption &gt; </P>4 O5 O5 E+ B; L" ]7 N
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>
6 _/ Q3 I( n% b! V! Z, M* n<P>{ </P>! Z! R  \1 P- n. h0 n* c; U
<P>ListView1- &gt;Items- &gt;Item[m]= </P>
& c+ @$ s7 T2 E# T<P>ListView1- &gt;Items- &gt;Item; </P>2 G9 ^9 i1 H% b0 Y& s
<P>ListView1- &gt;Items- &gt;Item= </P>
5 v. D' l2 m. x! z! n<P>ListView1- &gt;Items- &gt;Item[j]; </P>
6 k2 M; D( b8 j9 Z  U- Y  S<P>ListView1- &gt;Items- &gt;Item[j]= </P>  V/ V+ v* R6 I- g" e3 J
<P>ListView1- &gt;Items- &gt;Item[m]; </P>( ?5 k  j% L3 c6 j. Q- T) `
<P>} </P>% i' J3 s0 k( {6 j) {- X/ d* ^
<P>} </P># e: I4 k$ V5 g& S& k! p* G
<P>else </P>
8 i  k( C! V6 ~& T2 J! l<P>{ </P>
) g) F1 Z" l( T7 d6 @+ v<P>if(ListView1- &gt;Items- &gt;Item- &gt;Caption&lt; </P>/ {1 k  |- d: B2 r( m+ B
<P>ListView1- &gt;Items- &gt;Item[j]- &gt;Caption) </P>4 |1 m1 e" V2 ~, n! S6 [
<P>{ </P>
6 W* l& p) b( v5 Q8 G- U<P>ListView1- &gt;Items- &gt;Item[m]= </P>
: U- q3 M  R4 y; j# v! U+ O% t<P>ListView1- &gt;Items- &gt;Item; </P>3 r' [! A) a% \* ^0 U( u, D
<P>ListView1- &gt;Items- &gt;Item= </P>
& w$ m# p! l* a7 W5 |<P>ListView1- &gt;Items- &gt;Item[j]; </P>
0 `# M3 L/ ?/ |# a) e; s$ Z<P>ListView1- &gt;Items- &gt;Item[j]= </P>
+ B8 u# O' K/ r6 s8 b3 U4 a$ P) V<P>ListView1- &gt;Items- &gt;Item[m]; </P>
, e! \( u, k6 ?! c<P>} </P>. q+ J' m  H: ^1 {: S# L: a( Y
<P>} </P>
- D/ N9 V/ d4 ~5 `- s# E<P>ListView1- &gt;Items- &gt;Delete(m); </P>
' t# p2 J+ ~+ |8 _& p3 _<P>return; </P>1 |; N4 F. q5 v" r! C& p; K
<P>} </P>
5 D" p) l0 b  R<P>  </P>) v* P. I& |% R) k  i7 z
<P>---- 点击其它列时,需要将所点击的列内容从ListView1- &gt;Items- </P>
9 \4 X3 C( h3 }9 W5 m5 D+ Y<P>&gt;Item- &gt; SubItems- &gt;Text中抽出,并参照其进行排序。子项目在存储中,形 </P>
4 f' `. l  |! B, L# n* ~' i<P>式为_子项目1\r\n子项目2\r\n子项目3\r\n...子项目N\r\n_。为抽取其中某一 </P>
8 J+ c  I) t* c* ]<P>子项目,需编写如下函数,并将其放于void __fastcall TForm1:: </P>: c5 k, ~, G6 p
<P>ListView1ColumnClick前面即可。 </P>
# B' x  v: p2 x" N* Z<P>#include &lt; vcl/dstring.h &gt; </P>" s1 _. K: k8 \% ?+ o7 k
<P>AnsiString __stdcall sg(AnsiString str,int n) </P>
1 Q1 |- u4 l+ b" i% `<P>{ </P>
. g6 k8 ?3 i; D4 m2 h<P>int l,i; </P>9 e$ e2 d, `2 g8 z+ K
<P>AnsiString qq(str); </P>
& F9 t9 J! n2 A<P>l=qq.Length(); </P>; b9 }" n( T7 F' c  s6 j
<P>AnsiString p(str); </P>% w: E, |. a7 [( ~& ^
<P>char a[]="\r\n"; </P>
0 h" n1 X- U- r& N8 X. ~<P>int j=0,k=0; </P>  f9 s1 h- [, b
<P>for(j=1;j&lt; l;j++) </P>0 h. F: H/ w$ K9 T7 d* V$ y
<P>{ </P>8 Y  v# H7 T; J1 A8 y. d7 Q
<P>i=1; </P>
. q+ s8 L) x4 T9 ~4 S( |1 M<P>while(qq[j]!=a[0] &amp;&amp; qq[j+1]!=a[1]) </P>" ?4 N) v$ f& \+ t1 z; J. x
<P>{ </P>/ {5 B' j. J$ {& N. G
<P>p[i++]=qq[j]; </P>1 Y; s# ^7 ]6 }& ~
<P>j++; </P>
; B* F: D: {( X5 g: I8 [<P>} </P>
5 Y+ h4 Y2 r' H) c. c. L" Z5 |<P>k++; </P>
( i3 n* e$ @* N( p) M. C' u" x<P>if((k-1)==n) </P>
  l0 U1 h: v  J- A" a: Q<P>break; </P>, n) e) ^9 |8 G/ A, d2 R" G% |
<P>} </P>
& E2 Q: I/ ]& X1 S8 H/ x( }- _<P>p=NULL; </P>; \5 t+ I" S& b' S9 f: X, X
<P>return (p); </P>! T6 j: e) L+ h4 P, X1 V7 k- Z. _* r
<P>} </P>
' ?6 V# I0 q3 m! ~3 I; L- _<P>  </P>  a/ G/ ]+ j0 z7 K! |0 \7 Z
<P>---- 有了此函数以后,只需将上面的ListView1- &gt;Items- &gt;Item- </P>
% y) Z1 I- g9 ^% h+ y( c<P>&gt;Caption更换为sg(ListView1- &gt;Items- &gt;Item- &gt;SubItems- &gt;Text,n-1)即 </P>
9 [0 O# r1 Q8 n' }& M<P>可完成对此项目的点击排序功能。 </P>
; e# u5 X/ z0 w9 P9 f2 h- i9 o<P>for(i=0;i&lt; m-1;i++) </P>; f- T5 q; @9 I. \/ X* P
<P>for(j=i+1;j&lt; m;j++) </P>
0 k2 ~; n; ~, n<P>if(od) </P>
/ ]9 k8 V/ {7 x: K! {% f2 h+ k" Z<P>{ </P>2 [2 Q/ ?* w$ |) {6 {9 ~4 s
<P>if(sg(ListView1- &gt;Items- &gt; </P>
8 t0 s0 L( [' E, C<P>Item- &gt;SubItems- &gt;Text,n-1) &gt; </P>
  c4 x7 _* Q+ O. D' }' {<P>sg(ListView1- &gt;Items- &gt; </P>  b+ F6 m, P9 L0 \% r3 K; Q
<P>Item[j]- &gt;SubItems- &gt;Text,n-1)) </P>
' I1 ?* J, t7 v- M) A, P1 J! t
: i0 m  s; G# `' \- y( `$ A<P>// ...以下从略 </P>
9 w6 U9 Y  {: w" W: _<P>  </P>
1 M. R' J+ O# c# \" d  l6 U/ g<P>最后,删除临时的交换项目。 </P>! G; H  s: ?" Z" b  B
<P>ListView1- &gt;Items- &gt;Delete(m); </P>9 l% k# l/ K0 R0 [
<P>  </P>; I4 r9 o& N1 S
<P>---- 编译运行程序后,即会看到我们预期的结果。另外,本程序是按照字符串方 </P>8 k2 `; o3 q) t2 R6 c
<P>式进行排序的,如果需要按照数字或其它方式排序,只需进行相应的类型转换即可 </P>
3 E9 C1 r/ H  i. }) z9 r; 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, 2025-7-31 08:48 , Processed in 0.602205 second(s), 51 queries .

回顶部