如何让ListView切换显示多个同构List的内容的疑惑 ( 积分: 100 )

  • 主题发起人 主题发起人 cmd9x
  • 开始时间 开始时间
C

cmd9x

Unregistered / Unconfirmed
GUEST, unregistred user!
[:D]
VirsulListView可以用OwnerData方式加快显示速度,而且更灵活,
现有多个同构的数据存入不同的TList中,我希望能随意切换显示不同的TList中的内容,
用OnData方式显示数据,同时还需要设置TListView.Item.Count,好像涉及到了相互引用
烦恼了好久没有找到较好的方法,那位高手能指点一下,多谢了
 
看到同构两字,我真高兴,你就是知音人呀
希望你贴出关键代码,大家一起看
按你需要,是想做个有一定通用性的界面,切换总得有触发器,这个触发器可以是Menu,Combobox等,然后呼一个函数就是了
 
我随便整了一下,发现其实也不难,贴一下大概代码吧,算是问题圆满结束拉。
代码没加注释,共两个单元,第一个是处理方式类,第二个是数据管理类,管理类中实现了两个处理,添加记录时按序号使用不同的处理方式类,显示切换时用RegListView(序号)。
type
PInfoData=^TInfoData;
TInfoData=record
SID:string;
Caption:string;
end;
TChangeEvent=procedure (Sender: TObject;AChanged:Boolean) of object;
TListViewInfo=class
private
FInfoHash:TSafeHashList;
FList:TList;
FFirst:Pointer;
FLast:Pointer;
FChangeEvent:TChangeEvent;
function GetCount: Integer;
function GetItem(Idx: Integer): PInfoData;
public
constructor Create(OnCustChange:TChangeEvent);
destructor Destroy;overload;
procedure Add(Key:string;Data:TInfoData);
property DataCount:Integer read GetCount;
property ItemByIdx[Idx:Integer]:PInfoData read GetItem;
property OnChange:TChangeEvent read FChangeEvent write FChangeEvent;
end;
implementation

{ TListViewInfo }

procedure TListViewInfo.Add(Key: string; Data: TInfoData);
var Ptr:PInfoData;
OldIdx:Integer;
begin
Ptr:=FInfoHash.KeyOf(Key);
if Ptr=nil then
begin
New(Ptr);
Ptr^:=Data;
FInfoHash.Add(Key,Ptr);
FList.Insert(0,Ptr);
if Assigned(FChangeEvent) then FChangeEvent(Self,True);
end else
begin
OldIdx:=FList.IndexOf(Ptr);
if OldIdx>=0 then
Ptr^:=Data;
FList.Move(OldIdx,0);
if Assigned(FChangeEvent) then FChangeEvent(Self,False);
end;
end;

constructor TListViewInfo.Create(OnCustChange:TChangeEvent);
begin
FInfoHash:=TSafeHashList.Create(997);
FList:=TList.Create;
OnChange:=OnCustChange;
FFirst:=nil;
FLast:=nil;
end;

destructor TListViewInfo.Destroy;
var
Idx: Integer;
Data:PInfoData;
begin
for Idx := FList.Count - 1 downto 0 do
begin
Data:=PInfoData(FList.Items[Idx]);
Dispose(Data);
FList.Delete(Idx);
end;
FInfoHash.Free;
FList.Free;
inherited;
end;

function TListViewInfo.GetCount: Integer;
begin
Result:=FList.Count;
end;

function TListViewInfo.GetItem(Idx: Integer): PInfoData;
begin
Result:=nil;
if (Idx>=0)and(Idx<DataCount) then
Result:=FList.Items[Idx];
end;

type
TDataMgr=class
private
FList:TList;
FCurrListView:TListViewInfo;
FListView:TListView;
FHisPlay:Boolean;
function GetListViewData: TListViewInfo;
protected
procedure OnCustData(Sender: TObject; Item: TListItem);
procedure OnCustChange(Sender: TObject;AChanged:Boolean);
public
constructor Create(AListView:TListView);
destructor Destroy; override;
procedure RegListView(Idx:Integer);
procedure DoRefresh;
property ListViewData:TListViewInfo read GetListViewData;
end;

implementation

{ TDataMgr }

constructor TDataMgr.Create(AListView:TListView);
var ListView:TListViewInfo;
I:Integer;
begin
FList:=TList.Create;
for I:=0 to 1 do
begin
ListView:=TListViewInfo.Create(OnCustChange);
FList.Add(ListView);
end;
FCurrListView:=FList.Items[0];
FListView:=AListView;
FListView.DoubleBuffered:=True;
FListView.OwnerData:=True;
FListView.OnData:=OnCustData;
end;

destructor TDataMgr.Destroy;
begin
FList.Free;
inherited;
end;

procedure TDataMgr.DoRefresh;
begin
FListView.Items.Count:=ListViewData.DataCount;
FListView.Refresh;
end;

function TDataMgr.GetListViewData: TListViewInfo;
begin
Result:=FCurrListView;
end;

procedure TDataMgr.OnCustChange(Sender: TObject;AChanged:Boolean);
begin
if FCurrListView=Sender then
begin
if AChanged then
FListView.Items.Count:=FCurrListView.DataCount;//增加或减少了
end;
end;

procedure TDataMgr.OnCustData(Sender: TObject; Item: TListItem);
var ItemData:PListViewInfoData;
begin
ItemData:=PListViewInfoData(ListViewData.ItemByIdx[Item.Index]);

if ItemData<>nil then
with Item do begin
Caption:=ItemData^.SID;
SubItems.Add(ItemData^.Caption);
end;
end;

procedure TDataMgr.RegListView(Idx:Integer);
begin
if (Idx>=0)and(Idx<FList.Count) then
begin
FCurrListView:= FList.Items[Idx];
DoRefresh;
end;
end;
 
这两天周末没上网,我又来了
顺便品一下你的技术和代码风格:
论设计模块当与MVC相近,属多源,单显问题
中心类是TDataMgr,实例化时构造两份数据,默认选中第一套
TSafeHashList是自定义的数据容器,可称为数据存根
命名风格部分使用了匈牙力命名法,同是List类,
FInfoHash:TSafeHashList;
FList:TList;
显得有点不太统一
 
TSafeHashList其实也就是一个HASH表,便于快速定位指针,FList用于保存指针,因为它是有序的,而HASH表无序,所以不得以用个TList以便ListView.OnData用,目前暂时没有找到更好的方法.
 
后退
顶部