Board logo

Subject: 我想写个东西发给cnpack,但是有个问题,进来看吧 [Print This Page]

Author: SuperYoyoNC    Time: 2006-2-10 17:11     Subject: 我想写个东西发给cnpack,但是有个问题,进来看吧

在做一种类似一些软件的“选项”对话框所采用的形式,目的是不管是用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 ]
Author: flamingo    Time: 2006-2-16 02:08

WinMAP 没有使用新型的控件,他用的直接就是 Treeview ,Delphi 开源界中有个著名的
virtual Tree 可以看看。它几乎可以做到任何形式的效果。

Image Attachment: wamp.gif (2006-2-16 02:08, 18.33 K) / Download count 786
http://bbs.cnpack.org/attachment.php?aid=204


Author: SuperYoyoNC    Time: 2006-2-18 15:15     Subject: 不是啊

我没有说要做什么效果的TreeView,
我只是要做一个软件里通用的“选项设置”的系统,做到无论是TreeView+Frame,还是Tab+Pannel,还是其他什么形式的,都可以通用!!
Author: VictorWoo    Time: 2006-7-25 10:32

要是PageControl能够隐藏标题就好了
Author: Passion    Time: 2006-7-31 10:09

要隐藏标题的PageControl,不如用TNoteBook
Author: VictorWoo    Time: 2006-7-31 10:22

啊,win3.1面板里的控件都是古董级的了,还能焕发第二春?
研究看看呵呵
Author: csofter    Time: 2006-8-6 17:01

PageControl可以隐藏标题呀,把各个tab的tabvisible设成false就可以了
Author: 小雨哥    Time: 2007-5-22 01:09     Subject: 一个思维

我赞同这样的研究,但我要说的是不用这样去研究。

Delphi 确实存在组件、类库,那是比较底层的架构,而使用这些东西的时候,通常进入一种叫功能性框架的领域。这时候
注重的是如何实现功能。至于是使用Tree还是Tab,只要不影响功能实现,通常会根据界面要求取其一。二种在界面效果
上都有自身的优势,做成通用架构不需要定位在这二个东西上,更好的是定义一组访问接口,如此,即便是 Listbox 也一
样可以融合到这个通用架构来。这时,这个通用接口好比就是一个抽象层。

PageControl 是 Windows 基础类库里带的东西,NoteBook 却是原生的 Delphi 实现,与 Win3.1 本身没有关系。只是表
示这个东西历史悠久,但并不表示这东西是落伍的。

一点愚见,谨奉大鉴。
Author: 小笨象    Time: 2007-6-22 11:51

NoteBook 是我用得最多的控件之一。
原因之一就是能不显示标题。
说真的,我还真不知道csofter 说的方法。刚才一试, 白写这么多年程序了。
以后全部转用PageControl ,因为NoteBook里有些地方实在是很让人头痛。
Author: kendling    Time: 2007-6-25 10:23

使用TPageControl时要小心自带的热键:Ctrl+Tab和Ctrl+Shift+Tab
Author: jAmEs_    Time: 2007-7-20 09:48



QUOTE:
原帖由 小笨象 于 2007-6-22 11:51 发表
NoteBook 是我用得最多的控件之一。
原因之一就是能不显示标题。
说真的,我还真不知道csofter 说的方法。刚才一试, 白写这么多年程序了。
以后全部转用PageControl ,因为NoteBook里有些地方实在是很让人头痛 ...

我也不知道,但是其實這個不是我們的錯,因為TabVisible := false后,它的Visible也=False了。所以一直以來,我都以為這個只是隱藏整個頁面的。
事實上,這個屬性本來的意義也在于這樣,只是Visible := false后也可以顯示頁面罷了
Author: ExSystem    Time: 2007-7-21 19:47     Subject: 混,都有那么长时间了……还处于置顶

直接进CnPackI的群共享进行测试第一版的成品……




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0