最近写一个程序, 用到了点击列头排序, 从网上查了一下,不难,但是程序中用到了N多ListView,都要有这样的功能, 就自己写了一个专对ListView排序的类, 用起来很方便,
下面是排序类的代码 ( 怎么上传附件呢, 有人知道给我说一下. ):
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unit OrderListView;
interface
uses ComCtrls,SysUtils,StrUtils;
type
TOrderRule = (emAscending ,emDescending );
TListViewOrder = class
public
constructor Create(var listview : TListView);
function Compare(Item1, Item2: TListItem): integer;
procedure PreCompare(ColumnIndex : integer) ;
private
m_ListView : TListView;
m_Item1: TListItem;
m_Item2: TListItem;
m_Column : integer; //要排序的列
m_OrderRule : TOrderRule; //排序规则
procedure DrawArrow(ColumnIndex : integer );
procedure EraseArrow(ColumnIndex : integer );
end;
implementation
constructor TListViewOrder.Create(var listview : TListView);
begin
m_ListView := listview;
m_OrderRule := emAscending;
end;
procedure TListViewOrder.PreCompare(ColumnIndex : integer) ;
var
OldColumn : integer;
begin
OldColumn := m_Column; //保存前一次排序的列
m_Column := ColumnIndex;
if OldColumn = m_Column then //如果一个列点击两次
begin
if m_OrderRule = emAscending then m_OrderRule := emDescending else m_OrderRule := emAscending;
end
else
begin
m_OrderRule := emAscending;
end;
EraseArrow( OldColumn );
DrawArrow( m_Column );
m_ListView.AlphaSort;
end;
function TListViewOrder.Compare(Item1, Item2: TListItem) : integer; //点击列头排序
var
id, Compare : integer;
begin
if m_Column = 0 then //第一列
Compare := CompareText(Item1.Caption, Item2.Caption)
else
begin
id := m_Column - 1; //取得要sort 的 subitem 的 index
if id >= 0 then Compare := CompareText( item1.SubItems[id],item2.SubItems[id]);
end;
//若是要Descending
if m_OrderRule = emDescending then Compare := -Compare;
result := Compare;
end;
procedure TListViewOrder.DrawArrow(ColumnIndex : integer );
var
s1,s2 : string;
begin
s2 := m_listview.Column[ ColumnIndex ].Caption;
s2 := AnsiReplaceText( s2, '▼ ','');
s2 := AnsiReplaceText( s2, '▲ ','');
if m_OrderRule = emDescending then
s1 := '▼ ' + s2
else
s1 := '▲ ' + s2 ;
m_listview.Column[ ColumnIndex ].Caption := s1;
end;
procedure TListViewOrder.EraseArrow(ColumnIndex : integer );
var
s2 : string;
begin
s2 := m_listview.Column[ ColumnIndex ].Caption;
s2 := AnsiReplaceText( s2, '▼ ','');
s2 := AnsiReplaceText( s2, '▲ ','');
m_listview.Column[ ColumnIndex ].Caption := s2;
end;
end.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
使用:
use OrderListView,
....
m_order: TListViewOrder;
.....
在 Form 的 Create 事件中:
m_order := TListViewOrder.Create(ListView1);
在 ListView1 的 OnColumnClick 中:
m_order.PreCompare( Column.Index );
在ListView1 的 OnCompare 中
Compare := m_order.Compare(item1,item2);
就ok了.
只能实现对字符的排序,数值的就。。。了,而很多情况下需要对数值进行排序的。
顺便说一句我没用过上传附件,嘿嘿
对了还有按日期排序,这样就差不多了,建议楼主补全,呵呵
对数值和对时间可以修改
function TListViewOrder.Compare(Item1, Item2: TListItem) : integer;
为
type
TCompareType = ( emString, emDateTime, emNumber);
function TListViewOrder.Compare(Item1, Item2: TListItem; type: TCompareType) : integer;
嘿嘿, 偷懒了一下..................
下面是排序类的代码 ( 怎么上传附件呢, 有人知道给我说一下. ):
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unit OrderListView;
interface
uses ComCtrls,SysUtils,StrUtils;
type
TOrderRule = (emAscending ,emDescending );
TListViewOrder = class
public
constructor Create(var listview : TListView);
function Compare(Item1, Item2: TListItem): integer;
procedure PreCompare(ColumnIndex : integer) ;
private
m_ListView : TListView;
m_Item1: TListItem;
m_Item2: TListItem;
m_Column : integer; //要排序的列
m_OrderRule : TOrderRule; //排序规则
procedure DrawArrow(ColumnIndex : integer );
procedure EraseArrow(ColumnIndex : integer );
end;
implementation
constructor TListViewOrder.Create(var listview : TListView);
begin
m_ListView := listview;
m_OrderRule := emAscending;
end;
procedure TListViewOrder.PreCompare(ColumnIndex : integer) ;
var
OldColumn : integer;
begin
OldColumn := m_Column; //保存前一次排序的列
m_Column := ColumnIndex;
if OldColumn = m_Column then //如果一个列点击两次
begin
if m_OrderRule = emAscending then m_OrderRule := emDescending else m_OrderRule := emAscending;
end
else
begin
m_OrderRule := emAscending;
end;
EraseArrow( OldColumn );
DrawArrow( m_Column );
m_ListView.AlphaSort;
end;
function TListViewOrder.Compare(Item1, Item2: TListItem) : integer; //点击列头排序
var
id, Compare : integer;
begin
if m_Column = 0 then //第一列
Compare := CompareText(Item1.Caption, Item2.Caption)
else
begin
id := m_Column - 1; //取得要sort 的 subitem 的 index
if id >= 0 then Compare := CompareText( item1.SubItems[id],item2.SubItems[id]);
end;
//若是要Descending
if m_OrderRule = emDescending then Compare := -Compare;
result := Compare;
end;
procedure TListViewOrder.DrawArrow(ColumnIndex : integer );
var
s1,s2 : string;
begin
s2 := m_listview.Column[ ColumnIndex ].Caption;
s2 := AnsiReplaceText( s2, '▼ ','');
s2 := AnsiReplaceText( s2, '▲ ','');
if m_OrderRule = emDescending then
s1 := '▼ ' + s2
else
s1 := '▲ ' + s2 ;
m_listview.Column[ ColumnIndex ].Caption := s1;
end;
procedure TListViewOrder.EraseArrow(ColumnIndex : integer );
var
s2 : string;
begin
s2 := m_listview.Column[ ColumnIndex ].Caption;
s2 := AnsiReplaceText( s2, '▼ ','');
s2 := AnsiReplaceText( s2, '▲ ','');
m_listview.Column[ ColumnIndex ].Caption := s2;
end;
end.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
使用:
use OrderListView,
....
m_order: TListViewOrder;
.....
在 Form 的 Create 事件中:
m_order := TListViewOrder.Create(ListView1);
在 ListView1 的 OnColumnClick 中:
m_order.PreCompare( Column.Index );
在ListView1 的 OnCompare 中
Compare := m_order.Compare(item1,item2);
就ok了.
只能实现对字符的排序,数值的就。。。了,而很多情况下需要对数值进行排序的。
顺便说一句我没用过上传附件,嘿嘿
对了还有按日期排序,这样就差不多了,建议楼主补全,呵呵
对数值和对时间可以修改
function TListViewOrder.Compare(Item1, Item2: TListItem) : integer;
为
type
TCompareType = ( emString, emDateTime, emNumber);
function TListViewOrder.Compare(Item1, Item2: TListItem; type: TCompareType) : integer;
嘿嘿, 偷懒了一下..................