程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> ListView的排序

ListView的排序

編輯:關於C++

---- 列表框控件在應用程序中的使用率很高,在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編程起到良好作用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved