在做一种类似一些软件的“选项”对话框所采用的形式,目的是不管是用TreeView,还是用Tab,都可作出软件的“选项”对话框,现在正在实现一个TreeNodes和Frame结合的形式。
可能说不清楚。可以看一个图:
具体的问题,请先把这些声明看下去,自然就知道问题是什么了
Type
TBaseFrameClass = Class Of TBaseFrame; //对TBaseFrame的类引用
{* 关于TBaseFrame,在这里可以就当它是一个TFrame。}
TBaseFrameEvent = Procedure(Sender: TObject; Frame: TBaseFrame) Of Object;
TBasePreference = Class(TObject) //抽象基类
Protected
Procedure DoApply; Virtual; Abstract; //具体“应用”或者“确定”交给子类
Procedure DoReset; Virtual; Abstract; //具体“恢复默认值”交给子类
Procedure DoResetAll; Virtual; Abstract; //具体“全部恢复默认值”交给子类
Public
Procedure Apply; //响应“应用”或者“确定”命令
Procedure Reset; //响应“恢复默认值”命令
Procedure ResetAll; //响应“全部恢复默认值”命令
End;
TTreePreference = Class(TBasePreference) //使用TreeNodes来管理的子类
Protected
FItems: TTreeNodes;
FCurrItem: TTreeNode;
FRelatedTreeView: TCustomTreeView;
Procedure SetRelatedTreeView(TreeView: TCustomTreeView); Virtual; Abstract;
Public
Property RelatedTreeView: TCustomTreeView Read FRelatedTreeView Write
SetRelatedTreeView;
End;
TFrameTreePreference = Class(TTreePreference) //Frame和TreeNodes的结合
Private
FFrameOwner: Boolean;
FCurrFrame: TBaseFrame;
FNullFrame: TBaseFrame;
FOnApply: TBaseFrameEvent;
FOnReset: TBaseFrameEvent;
Procedure SetRelatedTreeView(TreeView: TCustomTreeView); Override;
Procedure DoApply; Override;
Procedure DoReset; Override;
Procedure DoResetAll; Override;
// 实际上,有点像在包装TTreeNodes
Procedure GetNodeFromIndex(Index: Integer);
Public
Constructor Create(NullFrame: TBaseFrame; FrameOwner: Boolean;
TreeNodesOwner: TCustomTreeView);
Destructor Destroy; Override;
// 实际上,有点像在包装TTreeNodes
Function AddChildObjectFirst(Parent: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Function AddChildObject(Parent: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Function AddObjectFirst(Sibling: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Function AddObject(Sibling: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Function AddNode(Node, Relative: TTreeNode; Const S: String; FrameType:
TBaseFrameClass; Method: TNodeAttachMode): TTreeNode;
Function AlphaSort(ARecurse: Boolean = False): Boolean;
Procedure Assign(Source: TPersistent); Override;
Procedure BeginUpdate;
Procedure Clear;
Function CustomSort(SortProc: TTVCompare; Data: Longint; ARecurse: Boolean =
False): Boolean;
Procedure Delete(Node: TTreeNode);
Procedure EndUpdate;
Function GetFirstNode: TTreeNode;
Function GetNode(ItemId: HTreeItem): TTreeNode;
Function InsertObject(Sibling: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Function InsertNode(Node, Sibling: TTreeNode; Const S: String; FrameType:
TBaseFrameClass): TTreeNode;
Property Count: Integer Read GetCount;
Property Item[Index: Integer]: TTreeNode Read GetNodeFromIndex;
{* 我的困惑就在Item属性的类型:TTreeNode上}
{因为现在这样注定是可以通过Item来随便篡改Data的指向的指针,就
是说,BaseFrame和TreeNode的关系就会乱掉!
现在我的解决办法是把这个属性定义修改成:
Property Item[Index: Integer]: TPreferenceNode,
当然,上面很多的TTreeNode都要改为TPreferenceNode,然后再定义
一个TPreferenceNode,也是在包装TTreeNode,只不过把Data属性给
修改了,变成Data是TBaseFrame类型的对象。这样就不会乱。
不过这样又要借助一个TObjectList,主要是用它的FindInstanceOf,
来查找TBaseFrame。这样会很复杂。有什么比这个更好的方法呢?
}
End;
[
Last edited by SuperYoyoNC on 2006-2-10 at 17:18 ]