- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用此代码来填充 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;
}
//---------------------------------------------------------------------------
问题 - 当最初调用 InitializeTree()
并分配 VirtualStringTree1->FocusedNode
时,它会被正确分配(不是 NULL)。
但是,如果在 OnNewText
中调用此 InitializeTree()
函数,以在重命名事件之后实际从数据库重新加载树 - 在分配 FocusedNode
后它仍然是 NULL。因此,显然树不能在 OnNewText
事件中重新加载和分配 FocusedNode
。
我实现了延迟调用来重新加载新树并重新分配FocusedNode - 通过实现一个快速而肮脏的计时器(可以使用PostMessage来延迟函数调用,但这只是一个愚蠢的例子) - 在内部分配之后一个计时器,它不再为 NULL 并且按预期工作。
任何人都可以指出我实现树重新加载的最佳方法是什么 - 比如使用特定事件,可以安全地设置新的 FocusedNode
并且不会将其重新分配回无效的?延迟函数调用是实现此目的的唯一方法还是有更好的事件可以捕获(例如,如果一个事件发生在 OnNewText
之后,如果该事件不允许设置焦点节点)。当然这可行,但我很感兴趣是否有更好的方法来做到这一点。
最佳答案
当您处于 tsEditing
树状态时,您无法更改 FocusedNode
,并且在离开 OnNewText
事件之前,您'就处于那种状态。 OnNewText
本身更多的是用于编辑验证;这是一个事件,您可以在其中修改编辑的值。相反,您应该使用 OnEdited
事件,该事件在编辑实际完成后触发。因此,将数据库更新和树重新加载内容移至此处,如以下 C++ Builder 伪代码所示:
void __fastcall TForm1::VirtualStringTree1Edited(TBaseVirtualTree *Sender,
PVirtualNode Node, TColumnIndex Column)
{
// update your database here; with VirtualStringTree1.Text[Node, Column] you
// can access the current node text after edit; when you update your DB, call
InitializeTree();
}
关于delphi - OnNewText 事件后何时重绘 VirtualTreeView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12868259/
我是一名优秀的程序员,十分优秀!