表是这样设计的
PROCLASSID 类别ID
PROCLASSNAME 类别名称
PROFCLASSID 上级类别 值是这样保存的:
类别ID 类别名称 上级类别
53 1111
54 2222 53
55 3333 54
56 444 55 这样的树该怎么写啊?sos!!!数据值不能修改
PROCLASSID 类别ID
PROCLASSNAME 类别名称
PROFCLASSID 上级类别 值是这样保存的:
类别ID 类别名称 上级类别
53 1111
54 2222 53
55 3333 54
56 444 55 这样的树该怎么写啊?sos!!!数据值不能修改
//...
end;ICategoryRepository = interface
function FindCategory(id: Integer): TCategory;
function FindCategories(category: TCategory): TCategoryList;
// procedure Add, Remove, etc.
end;再实现接口
TCategoryRepository = class(TInterfacedObject, ICategoryRepository)
private
fDataSet: TDataSet; // 比如类别是存在数据集里面的
public
constructor Create(dataSet: TDataSet); // 通过构造器传入
//...
function FindCategory(id: Integer): TCategory;
function FindCategories(category: TCategory): TCategoryList;
//...
end;具体实现其实很简单的。
KeyField, ParentField, TitleField: string);
{ 高效建树过程 by blazingfire 2008-05-21 }
type
PNodeData = ^TNodeData;
TNodeData = record
Key: Integer;
Parent: Integer;
Title: string;
Node: TTreeNode;
end; function CompareKey(Item1, Item2: Pointer): Integer;
begin
Result := PNodeData(Item1)^.Key - PNodeData(Item2)^.Key;
end; function BisearchNodeData(Key: Integer; SortedList: TList): PNodeData;
var
Lo, Hi, Mid: Integer;
begin
Lo := 0;
Hi := SortedList.Count - 1;
while Lo <= Hi do
begin
Mid := (Lo + Hi) div 2;
Result := SortedList[Mid];
if Key > Result^.Key then
Lo := Mid + 1
else if Key < Result^.Key then
Hi := Mid - 1
else
Exit {至此已经找到};
end;
Result := nil;
end; procedure BuildNode(nData: PNodeData; SortedList: TList);
var
ParentData: PNodeData;
begin
if nData^.Node = nil then
begin
//折半查找父级PNodeData
ParentData := BisearchNodeData(nData^.Parent, SortedList);
//父级为空或是本身,就建一个根节点
if (ParentData = nil) or (ParentData = nData) then
nData^.Node := TreeView.Items.AddChild(nil, nData^.Title)
else
begin
if ParentData.Node = nil then
BuildNode(ParentData, SortedList);
nData^.Node := TreeView.Items.AddChild(ParentData.Node, nData^.Title);
end;
end;
end;var
List, SortedList: TList;
i: Integer;
nData: PNodeData;
fldKey, fldParent, fldTitle: TField;
begin
TreeView.Items.BeginUpdate;
List := TList.Create;
try
fldKey := DataSet.FieldByName(KeyField);
fldParent := DataSet.FieldByName(ParentField);
fldTitle := DataSet.FieldByName(TitleField);
TreeView.Items.Clear; DataSet.DisableControls;
try
//把数据集的数据加载到内存,以备在内存里建树
DataSet.First;
while not DataSet.Eof do
begin
New(nData);
nData^.Key := fldKey.AsInteger;
nData^.Parent := fldParent.AsInteger;
nData^.Title := fldTitle.AsString;
nData^.Node := nil;
List.Add(nData);
DataSet.Next();
end;
finally
DataSet.EnableControls;
end; SortedList := TList.Create;
try
SortedList.Assign(List);
SortedList.Sort(@CompareKey); //以Key排序,以备用折半查找
for i := 0 to List.Count - 1 do
BuildNode(List[i], SortedList);
finally
SortedList.Free;
end;
finally
TreeView.Items.EndUpdate;
for i := 0 to List.Count - 1 do
Dispose(List[i]);
List.Free;
end;
end;
调用例子:procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT PROCLASSID,PROFCLASSID,PROCLASSNAME from TableName';
ADOQuery1.Open;
BuildTree(TreeView1, ADOQuery1, 'PROCLASSID', 'PROFCLASSID', 'PROCLASSNAME');
end;