ListView的排序
—- 列表框控件在应用措施中的利用率很高,在windows中常常见到,它有四种常见的式样,别离具有显示大图标,小方针,含有图标的多列列表,含有列标头的列表。我们也常常见到一些扩展成果,譬喻我们在资源打点器中的文件列表框中,在选用具体资料察看时,用鼠标单击列标头,如巨细,则所列文件按巨细排序;单机日期,则按文件日期举办排序.这一成果加强了应用措施的可用性,使操纵更直观、利便。笔者在以Borland C++Builder 3.0(以下简称BCB)作为开拓平台实现这一成果时发明,仅通过设定列表框控件的属性值的要领,只能按照项目标首列加以排序,不能按照子项目(SubItems)排序。因此,我们需要编写本身的代码以完成这一成果。
—- 以下描写如安在BCB开拓平台上为列表框添加列标头点击排序成果,当我们点击的次数为奇数时,所列内容以降序分列;当我们点击的次数为偶数时,所列内容以升序分列。
—- 首先将一个列表框控件安顿在Form上,并将其名称设为ListView1。然后在个中添加若干项目作为试验工具。要领为:用鼠标右键单击控件,在弹出的对话框中选择Columns Editor用来添加列和子列;再选Items Editor用来添加项目(包括子列和主列上的内容)。
—- 为了显示出子项目内容,需要在Object Inspector中修改ListView属性值,将ViewStyle配置为vsReport。别的,还必需将SortType配置为None,以使我们的排序措施起浸染。这样,措施的外观已经切合需要,下面应该增加排序成果的代码了。为此需要添加类的要领到源代码中。添加位置为:
void __fastcall TForm1::ListView1ColumnClick
(TObject *Sender,
TListColumn *Column)
—- 在该要领的通报参数中,指向TListColumn范例的指针Column中含有用户所点击的列的信息。
—- 下面先界说变量:
int i,m,n,j;
static bool od=true;
od=!od;
—- od代表用户点击的次数,奇数时为true,偶数时为false。留意此处od的存储范例设定为static,可以担保其数值的持续性。用n记任命户点击的列号,m记录列表框中的总项目数。
n=Column- >Index;
m=ListView1- >Items- >Count;
—- 在列表框中姑且添加一个项目作为排序中互换用的姑且空间。
ListView1- >Items- >Add();
—- 当用户点击第一列列标头时,排序按ListView1- >Items- >Item[i]- >Caption举办,与其它列差异,所以要单独举办排序。
if (n==0)
{
for(i=0;i< m-1;i++)
for(j=i+1;j< m;j++)
if(od)
{
if(ListView1- >Items- >Item[i]- >Caption >
ListView1- >Items- >Item[j]- >Caption)
{
ListView1- >Items- >Item[m]=
ListView1- >Items- >Item[i];
ListView1- >Items- >Item[i]=
ListView1- >Items- >Item[j];
ListView1- >Items- >Item[j]=
ListView1- >Items- >Item[m];
}
}
else
{
if(ListView1- >Items- >Item[i]- >Caption<
ListView1- >Items- >Item[j]- >Caption)
{
ListView1- >Items- >Item[m]=
ListView1- >Items- >Item[i];
ListView1- >Items- >Item[i]=
ListView1- >Items- >Item[j];
ListView1- >Items- >Item[j]=
ListView1- >Items- >Item[m];
}
}
ListView1- >Items- >Delete(m);
return;
}
—- 点击其它列时,需要将所点击的列内容从ListView1- >Items- >Item[i]- > SubItems- >Text中抽出,并参照其举办排序。子项目在存储中,形式为_子项目1\r\n子项目2\r\n子项目3\r\n…子项目N\r\n_。为抽取个中某一子项目,需编写如下函数,并将其放于void __fastcall TForm1::ListView1ColumnClick前面即可。
#include < vcl/dstring.h >
AnsiString __stdcall sg(AnsiString str,int n)
{
int l,i;
AnsiString qq(str);
l=qq.Length();
AnsiString p(str);
char a[]="\r\n";
int j=0,k=0;
for(j=1;j< l;j++)
{
i=1;
while(qq[j]!=a[0] && qq[j+1]!=a[1])
{
p[i++]=qq[j];
j++;
}
k++;
if((k-1)==n)
break;
}
p[i]=NULL;
return (p);
}
—- 有了此函数今后,只需将上面的ListView1- >Items- >Item[i]- >Caption改换为sg(ListView1- >Items- >Item[i]- >SubItems- >Text,n-1)即可完成对此项目标点击排序成果。
for(i=0;i< m-1;i++)
for(j=i+1;j< m;j++)
if(od)
{
if(sg(ListView1- >Items- >
Item[i]- >SubItems- >Text,n-1) >
sg(ListView1- >Items- >
Item[j]- >SubItems- >Text,n-1))
// ...以下从略
最后,删除姑且的互换项目。
ListView1- >Items- >Delete(m);
—- 编译运行措施后,即会看到我们预期的功效。别的,本措施是凭据字符串方法举办排序的,假如需要凭据数字或其它方法排序,只需举办相应的范例转换即可。领略本措施后,读者即把握了对ListView控件编程的一条根基思路,对此后利用BCB以及对windows编程起到精采浸染。