CSDN博客

img nxyc_twz

C++Builder 高手进阶 (三)用BCB设计DBTreeView组件

发表于2003/1/29 13:58:00  1422人阅读

分类: BCB

 

C++Builder 高手进阶 

nxyc_twz@163.com

 

前段时间买了本书《C++ Builder深度历险》,暂且不论这本书写的如何,但其作者独特的写作角度令我折服。于是我就有了个想法,能不能将自己多年从事软件开发的经验写成一系列的文章在CSDN上与大家分享,这样不但可使自己的编程水平得到提高,同时又可与CSDN上众多的高手相互砌磋,又何乐而不为呢?在我的写作计划中,将主要包括C++Builder 高手进阶 》、《Interbase 使用技巧》、《ODAC使用详解》等一系列内容。其中C++Builder 高手进阶 将主要通过实例讲解API函数的应用、用BCB编写组件、BCBMIS系统中的应用等;Interbase 使用技巧》(我最喜欢用的数据库Server)则主要讲述其各种使用技巧;ODAC使用详解》(我用BCB连接ORACLE时的首选)主要是以翻译ODAC的帮助文件为主,并辅以我在实际应用中的技巧。希望我的想法能得到大家的支持!

 

(三)用BCB设计DBTreeView组件

 

一、         系统分析

现在使用BCB的以越来越多,可是你有没有意识到,你所使用的控件究竟有几个是用C++编写的?答案肯定让人无法忍受,既然无法忍受何不亲自操刀写一套属于BCB自己的组件呢?我希望从我开始,众位高手能同心协力,共同打造真正属于BCB自己的组件!我不想讲述BCB设计组件的基础知识,因为这些在《C++Builder 5开发人员指南》中有详细的介绍。

我们所设计的DBTreeView派生自TtreeView组件,因此它将具有TtreeView组件的一切特性,我们要做的就是使其具有数据感知能力,与数据直接连接进行直接通信。要构造Tree形结构,我们应使每一个节点具备如下特征:每个节点有一个唯一标识符ID和一个父标识ParentID,(最顶层节点的Parent为空)为了显示相关内容,则还需要一上显示字段FDisplayField。该组件的工作原理已经很清晰了:通过每个节点的IDParentID定位数据记录,然后将相关字段内容赋给FdisplayField显示。

二、         开发前沿

该组件中最重的技术莫过于数据感知了,下面就介绍一下数据感知 技术:

要使某个组件成为数据感知的,我们必须给它提供所需的数据连接以便和数据训数据成员通信,这个数据连接类是TFieldDataLink。数据感知组件有其自己的数据连接类,数据连接由组件负责创建、初始化和销毁。建立连接通常需要3步:

1.  将数据连接类(TFieldDataLink)声明为组件的成员;

2.  声明适当的读、写访问属性;

3.  初始化数据连接。

三、         设计流程

//DBTreeView头文件

/在头文件中添加以下三行,因为/数据连接类需要这三个头文件中的声明

#include <Db.hpp>     

#include <DbTables.hpp>

#include <DbCtrls.hpp>

//定义事件,用来响应设置节点位图事件

typedef void __fastcall (__closure *TDBTVSetImageIndexEvent)(System::TObject* Sender, int ID, int ParentID, int Level, int& ImageIndex, int& SelectedIndex);

//定义节点结构

struct TDBTreeNodeData

{

    int ID;        //节点唯一标识

    int ParentID;   //节点父标识,它为空时表示此节点是最顶层节点

};

 

class PACKAGE TDBTreeView : public TTreeView

{

private:

    TFieldDataLink* FDataLink;   //声明数据连接成员

    AnsiString FParentIDField;    //父标识字段

    AnsiString FPrimaryIDField;   //主标识字段

    AnsiString FDisplayField;     //显示字段

    bool FActive;               //是否为活动状态

    bool FAllowModifyDB;       //是否允许修改

    TDBTVSetImageIndexEvent   FOnSetImageIndex;   //声明事件

 

    void __fastcall SetActive(bool Value);   //设置状态

void __fastcall SetDataSource(Db::TDataSource* Value); //设置数据源

    TDataSource* __fastcall GetDataSource(); //取得数据源

 

    void __fastcall ClearAllNodes();  //删除所有节点

    void __fastcall FillTreeNodes(int ParentID, TTreeNode* Node); //填充节点

    void __fastcall FillChildTreeNodes(int ParentID, TTreeNode* Node, bool Nest = false); //填充子节点

    void __fastcall AddDataToNode(TTreeNode* Node, TDBTreeNodeData& Data);//追加数据到节点

protected:

//以下以个方法用来重载TreeView的相关方法

     virtual void __fastcall Loaded(void); //Load方法

     virtual void __fastcall Notification(Classes::TComponent* AComponent, Classes::TOperation Operation); //事件

     DYNAMIC void __fastcall Edit(const tagTVITEMA &Item);//Edit方法

     DYNAMIC void __fastcall Expand(TTreeNode* Node);//Expand方法

     DYNAMIC void __fastcall KeyDown(Word &Key, Classes::TShiftState Shift);//键盘事件

     DYNAMIC void __fastcall Change(TTreeNode* Node);//节点改变事件

     virtual bool __fastcall CustomDrawItem(TTreeNode* Node, TCustomDrawState State, TCustomDrawStage Stage, bool &PaintImages);//自绘节点事件

 

public:

    __fastcall TDBTreeView(TComponent* Owner);//构造函数

    __fastcall ~TDBTreeView();//析构函数

 

    TDBTreeNodeData __fastcall GetNodeData(TTreeNode* Node);//取得指定节点数据

void __fastcall FullExpand(void);  //展开所有节点

    __property bool Active = {read = FActive, write = SetActive};//属性活动状态

__published:

//以下定义在属性编辑器中用到的几个属性

    __property bool AllowModifyDB = {read = FAllowModifyDB, write = FAllowModifyDB};//是否允许编辑

    __property AnsiString ParentIDField = {read = FParentIDField, write = FParentIDField};//父标识

    __property AnsiString PrimaryIDField = {read = FPrimaryIDField, write = FPrimaryIDField};//主标识

    __property AnsiString DisplayField = {read = FDisplayField, write = FDisplayField};//显示字段

     __property TDataSource* DataSource = {read=GetDataSource, write=SetDataSource};//数据源

    __property TDBTVSetImageIndexEvent OnSetImageIndex = {read=FOnSetImageIndex, write=FOnSetImageIndex};//设置节点位图事件

};

//下面的类用来填充字段列表

class TFieldNameProperty : public TStringProperty

{

public:

    TPropertyAttributes __fastcall GetAttributes(void)

    {

        return TPropertyAttributes() << paValueList;

    }

 

     void __fastcall GetValues(Classes::TGetStrProc Proc);

};

 《未完待续》

 

 

 

0 0

相关博文

我的热门文章

img
取 消
img