//续二
void __fastcall TDBTreeView::FillChildTreeNodes(int ParentID, TTreeNode* Node, bool Nest)
{//用指定值填充子节点
TQuery* AQuery = new TQuery(this);//创建一个数据集控件
AnsiString strSql, strText;
int iID, iParentID;
int iImageIndex, iSelectedIndex;
TTreeNode* TreeNode;
TDBTreeNodeData NodeData;
//设置数据集的各项参数
AQuery->DatabaseName = ((TTable*)(FDataLink->DataSource->DataSet))->DatabaseName;//设置数据库名
AQuery->Close();//关闭数据集
AQuery->SQL->Clear();//清空原SQL语句
strSql = "SELECT * FROM " + ((TTable*)(FDataLink->DataSource->DataSet))->TableName + " WHERE ";
strSql += FParentIDField + "=:PID";
AQuery->SQL->Add(strSql);//指定新的SQL语句
AQuery->ParamByName("PID")->AsInteger = ParentID;
AQuery->Open();//打开数据集
this->Items->BeginUpdate();//开始更新DBTreeView组件显示
while (!AQuery->Eof)//未到数据集尾部
{
strText = AQuery->FieldByName(FDisplayField)->AsString;//取得显示字段内容
iID = AQuery->FieldByName(FPrimaryIDField)->AsInteger;//取得主标识字段内容
iParentID = AQuery->FieldByName(FParentIDField)->AsInteger;//取得父标识字段内容
TreeNode = this->Items->AddChild(Node, strText);//将上面取得的相关数据追加到新节点
iImageIndex = iSelectedIndex = -1;//设置节点位图与选中时位图
if (FOnSetImageIndex) FOnSetImageIndex(this, iID, iParentID, TreeNode->Level, iImageIndex, iSelectedIndex);//如果设置位图发生变化,则触发相关事件
TreeNode->ImageIndex = iImageIndex;//设置节点位图及选中时位图
TreeNode->SelectedIndex = iSelectedIndex;
NodeData.ID = iID;//取得节点主标识,父标识,并按其追加一个新节点
NodeData.ParentID = iParentID;
AddDataToNode(TreeNode, NodeData);
if (Nest) FillChildTreeNodes(iID, TreeNode);//如果指定参数Nest为true,则递归调用以填充所有子节点
AQuery->Next();//移动到下一条记录
}
this->Items->EndUpdate();//结束DBTreeView组件更新
AQuery->Close();//关闭数据集
delete AQuery;//删除临时创建的数据集控件
}
void __fastcall TDBTreeView::AddDataToNode(TTreeNode* Node, TDBTreeNodeData& Data)
{//追加数据到节点
TDBTreeNodeData* pData = new TDBTreeNodeData;
*pData = Data;
Node->Data = pData;
}
//---------------------------------------------------------------------------
TDBTreeNodeData __fastcall TDBTreeView::GetNodeData(TTreeNode* Node)
{//取得指定节点的数据
return *(TDBTreeNodeData*)(Node->Data);
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::Loaded(void)
{//调用原Load方法
TCustomTreeView::Loaded();
/* TODO : Loaded */
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::Notification(Classes::TComponent* AComponent, Classes::TOperation Operation)
{
//事件响应
TCustomTreeView::Notification(AComponent, Operation);//调用原方法
if ((Operation == opRemove) && (FDataLink != NULL) && (AComponent == DataSource))//如果操作为opRemove以及数据连接不为空且指定组件为数据源,则
DataSource = NULL;//使数据源为空
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::Edit(const tagTVITEMA &Item)
{//编辑节点
TCustomTreeView::Edit(Item);//调用原方法
if (FAllowModifyDB)//如果允许修改,则
{
TTreeNode* Node;
AnsiString DatabaseName = ((TTable*)(FDataLink->DataSource->DataSet))->DatabaseName;
AnsiString TableName = ((TTable*)(FDataLink->DataSource->DataSet))->TableName;
TDBTreeNodeData NodeData;
TQuery* AQuery = new TQuery(this);//新建一个数据集
AnsiString strSql;
if ((Item.state & TVIF_PARAM) != 0) Node = (TTreeNode*)(Item.lParam);
else Node = Items->GetNode(Item.hItem);
NodeData = GetNodeData(Node);
strSql = "UPDATE " + TableName + " SET " + FDisplayField + " =:NewDispText WHERE " + FPrimaryIDField + "=:ID";//用指定条件更新数据集
AQuery->Close();//关闭数据集
AQuery->DatabaseName = DatabaseName;//设置数据库连接
AQuery->SQL->Clear();//清空原SQL语句
AQuery->SQL->Add(strSql);//追加SQL语句
AQuery->ParamByName("NewDispText")->AsString = Node->Text;//对SQL中的参数进行赋值
AQuery->ParamByName("ID")->AsInteger = NodeData.ID;
AQuery->ExecSQL();//打开数据集
delete AQuery;//删除临时创建的数据集控件
}
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::Expand(TTreeNode* Node)
{//展开指定节点
TCustomTreeView::Expand(Node);//调用原原方法
TDBTreeNodeData NodeData;
TTreeNode* ANode;
for (ANode = Node->getFirstChild(); ANode; ANode = Node->GetNextChild(ANode))//遍历指定节点的子节点
{
NodeData = GetNodeData(ANode);//取得节点数据
if (ANode->Count == 0)//如果节点数据为0,则填充其子节点
FillChildTreeNodes(NodeData.ID, ANode);
}
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::KeyDown(Word &Key, Classes::TShiftState Shift)
{
//键盘处理
TWinControl::KeyDown(Key, Shift);//调用原键盘处理方法
if (Key == VK_F2 && Shift == TShiftState())//如果是Shift+F2则
{
/* Handle 'F2' key */
if (this->Selected != NULL)//编辑当前选中的节点
this->Selected->EditText();
}
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::Change(TTreeNode* Node)
{//处理节点发生变化事件
TCustomTreeView::Change(Node);//调用原方法
static TTreeNode* OldNode = NULL;
TTreeNode* SelectedNode = this->Selected;//取得已选节点指针
TDBTreeNodeData NodeData;
TTable *ATable = (TTable*)(FDataLink->DataSource->DataSet);//指定数据集
if (OldNode == SelectedNode) return;//如果旧节点等于选中的节点则直接返回
if (ATable == NULL) return;//如果数据集为空则直接返回
if (SelectedNode == NULL) return;//如果没有已选节点则直接返回
NodeData = GetNodeData(SelectedNode);//取得指定节点数据
ATable->SetKey();//按指定条件查找数据记录
ATable->FieldByName(FPrimaryIDField)->AsInteger = NodeData.ID;
ATable->GotoKey();
OldNode = SelectedNode;//旧节点等于现在已选节点
}
//---------------------------------------------------------------------------
bool __fastcall TDBTreeView::CustomDrawItem(TTreeNode* Node, TCustomDrawState State, TCustomDrawStage Stage, bool &PaintImages)
{
//自绘节点
bool Result;//调用原自绘方法
Result = TCustomTreeView::CustomDrawItem(Node, State, Stage, PaintImages);
/* TODO : ... */
//TDBTreeNodeData NodeData = GetNodeData(Node);
return Result;
}
//---------------------------------------------------------------------------
void __fastcall TDBTreeView::FullExpand(void)
{//展开所有节点
if (!Active)//如果DBTreeView不是活动状态,则抛出一个异常
throw Exception("DBTreeView is Inactive.");
this->Items->BeginUpdate();//开始更新DBTreeView
ClearAllNodes();//清空所有节点
FillChildTreeNodes(0, NULL, true);//填充子节点
this->Items->EndUpdate();//结束更新
TCustomTreeView::FullExpand();//调用原方法实现展开所有节点
}
//---------------------------------------------------------------------------
void __fastcall TFieldNameProperty::GetValues(Classes::TGetStrProc Proc)
{//取得字段值
int i;
TDBTreeView* ADBTreeView;
ADBTreeView = (TDBTreeView*)GetComponent(0);
if (ADBTreeView->DataSource != NULL)//如果DBTreeView的数据源不为空,则
{//遍历所有字段,并将其填充到相关字段属性中
for (i = 0; i < ADBTreeView->DataSource->DataSet->FieldCount; i ++)
Proc(ADBTreeView->DataSource->DataSet->Fields->Fields[i]->FieldName);
}
else
{//否则抛出异常
throw Exception("Missing DataSource property.");
}
}
TTypeInfo* AnsiStringTypeInfo(void)
{
//定义类型信息
TTypeInfo* TypeInfo = new TTypeInfo;
TypeInfo->Name = "AnsiString";
TypeInfo->Kind = tkLString;
return TypeInfo;
}
《未完,见一篇DBTreeView开发总结》
本文地址:http://com.8s8s.com/it/it29443.htm