Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi OnNewText事件后何时重新绘制VirtualTreeView?_Delphi_C++builder_Virtualtreeview_Tvirtualstringtree - Fatal编程技术网

Delphi OnNewText事件后何时重新绘制VirtualTreeView?

Delphi OnNewText事件后何时重新绘制VirtualTreeView?,delphi,c++builder,virtualtreeview,tvirtualstringtree,Delphi,C++builder,Virtualtreeview,Tvirtualstringtree,我使用此代码填充VirtualStringTree并允许重命名项目: //--------------------------------------------------------------------------- // Structure for the tree //--------------------------------------------------------------------------- struct TVSTdata { UnicodeString N

我使用此代码填充VirtualStringTree并允许重命名项目:

//---------------------------------------------------------------------------
// Structure for the tree
//---------------------------------------------------------------------------
struct TVSTdata
{
UnicodeString Name;
};
//---------------------------------------------------------------------------
// Initialization of the tree
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
VirtualStringTree1->NodeDataSize = sizeof(TVSTdata);
// Fill all nodes with initial data
InitializeTree();
}
//---------------------------------------------------------------------------
// Fill all nodes with data and assign FocusedNode
//---------------------------------------------------------------------------
void TForm1::InitializeTree()
{
TVirtualNode* pNode;
TVirtualNode* pActiveNode;
TVSTdata*     pData;

VirtualStringTree1->BeginUpdate();
VirtualStringTree1->Clear();

pNode = VirtualStringTree1->AddChild(NULL); pData = static_cast<TVSTdata*>(VirtualStringTree1->GetNodeData(pNode)); pData->Name = "This is name 1";
pNode = VirtualStringTree1->AddChild(NULL); pData = static_cast<TVSTdata*>(VirtualStringTree1->GetNodeData(pNode)); pData->Name = "This is name 2";
pNode = VirtualStringTree1->AddChild(NULL); pData = static_cast<TVSTdata*>(VirtualStringTree1->GetNodeData(pNode)); pData->Name = "This is name 3"; pActiveNode = pNode;
pNode = VirtualStringTree1->AddChild(NULL); pData = static_cast<TVSTdata*>(VirtualStringTree1->GetNodeData(pNode)); pData->Name = "This is name 4";
pNode = VirtualStringTree1->AddChild(NULL); pData = static_cast<TVSTdata*>(VirtualStringTree1->GetNodeData(pNode)); pData->Name = "This is name 5";

VirtualStringTree1->Selected[pActiveNode] = true;
VirtualStringTree1->FocusedNode = pActiveNode; // PROBLEM -> if assigned from within OnNewText will still remain NULL and won't be set to pActiveNode!
VirtualStringTree1->EndUpdate();
}
//---------------------------------------------------------------------------
// Just display the text
//---------------------------------------------------------------------------
void __fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType, UnicodeString &CellText)
{
TVSTdata* pData = static_cast<TVSTdata*>(Sender->GetNodeData(Node));
CellText = pData->Name;
}
//---------------------------------------------------------------------------
// Allow editing
//---------------------------------------------------------------------------
void __fastcall TForm1::VirtualStringTree1Editing(TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column, bool &Allowed)
{
Allowed = true;
}
//---------------------------------------------------------------------------
// Now this is where ideally I would reload the tree with new data - after rename
//---------------------------------------------------------------------------
void __fastcall TForm1::VirtualStringTree1NewText(TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column, UnicodeString NewText)
{
NewText = "not important for this example as tree is reloaded anyway";
InitializeTree();  // ERROR is here - after assigning FocusedNode it is still NULL
//Timer1->Enabled = true; // If delayed call FocusedNode is correctly assigned and not NULL
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//InitializeTree();
//Timer1->Enabled = false;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//树的结构
//---------------------------------------------------------------------------
结构TVSTdata
{
独角兽名称;
};
//---------------------------------------------------------------------------
//树的初始化
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent*Owner):TForm(Owner)
{
VirtualStringTree1->NodeDataSize=sizeof(TVSTdata);
//用初始数据填充所有节点
InitializeTree();
}
//---------------------------------------------------------------------------
//用数据填充所有节点并分配FocusedNode
//---------------------------------------------------------------------------
void TForm1::InitializeTree()
{
TVirtualNode*pNode;
TVirtualNode*pActiveNode;
TVSTdata*pData;
VirtualStringTree1->BeginUpdate();
VirtualStringTree1->Clear();
pNode=VirtualStringTree1->AddChild(NULL);pData=static_cast(VirtualStringTree1->GetNodeData(pNode));pData->Name=“这是名称1”;
pNode=VirtualStringTree1->AddChild(NULL);pData=static_cast(VirtualStringTree1->GetNodeData(pNode));pData->Name=“这是名称2”;
pNode=VirtualStringTree1->AddChild(NULL);pData=static_cast(VirtualStringTree1->GetNodeData(pNode));pData->Name=“这是名称3”;pActiveNode=pNode;
pNode=VirtualStringTree1->AddChild(NULL);pData=static_cast(VirtualStringTree1->GetNodeData(pNode));pData->Name=“这是名称4”;
pNode=VirtualStringTree1->AddChild(NULL);pData=static_cast(VirtualStringTree1->GetNodeData(pNode));pData->Name=“这是名称5”;
VirtualStringTree1->所选[pActiveNode]=true;
VirtualStringTree1->FocusedNode=pActiveNode;//问题->如果从onneText中分配,仍将保持空值,并且不会设置为pActiveNode!
VirtualStringTree1->EndUpdate();
}
//---------------------------------------------------------------------------
//只需显示文本即可
//---------------------------------------------------------------------------
void u fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree*发送方、PVirtualNode节点、TColumnIndex列、TVSTTextType TextType、UnicodeString和CellText)
{
TVSTdata*pData=static_cast(发送方->获取节点数据(节点));
CellText=pData->Name;
}
//---------------------------------------------------------------------------
//允许编辑
//---------------------------------------------------------------------------
void _fastcall TForm1::VirtualStringTree1Editing(TBaseVirtualTree*发送方、PVirtualNode节点、TColumnIndex列、bool&允许)
{
允许=真;
}
//---------------------------------------------------------------------------
//现在,理想情况下,我会在重命名后用新数据重新加载树
//---------------------------------------------------------------------------
void _fastcall TForm1::VirtualStringTree1NewText(TBaseVirtualTree*发送方、PVirtualNode节点、TColumnIndex列、UnicodeString NewText)
{
NewText=“对于本例不重要,因为树仍将重新加载”;
InitializeTree();//此处有错误-分配FocusedNode后仍然为NULL
//Timer1->Enabled=true;//如果延迟调用FocusedNode分配正确且不为NULL
}
//---------------------------------------------------------------------------
void _fastcall TForm1::Timer1Timer(TObject*发送方)
{
//InitializeTree();
//Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
问题-当最初调用
InitializeTree()
并分配
VirtualStringTree1->FocusedNode
时,该问题被正确分配(非空)

但是,如果在
OnNewText
中调用此
InitializeTree()
函数,以在重命名事件后从数据库中实际重新加载树-在分配
FocusedNode
后,它将保持为空。因此,显然不能从
OnNewText
事件中重新加载和分配树
FocusedNode

我实现了延迟调用以重新加载新树并重新分配
FocusedNode
——通过实现一个快速且脏的计时器(可以将PostMessage用于延迟函数调用,但这只是一个愚蠢的示例)——在计时器内分配后,它不再为NULL,并按预期工作


有人能告诉我实现树的重新加载的最佳方法是什么吗?比如说要使用的特定事件,在该事件中可以安全地设置新的
FocusedNode
,并且不会将其重新分配回NULL?延迟函数调用是否是实现此目的的唯一方法,或者是否有更好的事件可捕获(例如,如果某个事件发生在
OnNewText
之后,如果此事件不允许设置聚焦节点)。当然,这是可行的,但我对是否有更好的方法感兴趣。

当您处于
t编辑
树状态时,您不能更改
FocusedNode
,除非您离开
OnNewText
事件,否则您处于该状态。
OnNewText
本身更适合编辑验证;它是一个事件,您可以在其中修改编辑的值。相反,您应该使用
oneedid
事件,该事件在实际完成编辑后触发。因此,移动数据库更新和树重加载的东西,如下面的C++ Builder伪代码:

void\uu fastcall TForm1::VirtualStringTree1Edited(TBaseVirtualTree*发送方,
PVirtualNode节点,TColumnIndex列)
{
//在此处更新您的数据库;使用VirtualStringTree1.Text[Node,Column]更新您的数据库
//编辑后可以访问当前节点文本;更新数据库时,请调用
InitializeTree();
} 

如果您谈论的是数据库,那么当您只编辑一个节点时,是否真的需要重新加载整个树?您不希望在y时更新特定行吗