3

このコードを使用して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ではありません)。

ただし、このInitializeTree()関数が内部で呼び出されOnNewText、名前変更イベントの後にデータベースからツリーを実際に再ロードする場合、割り当て後FocusedNodeはNULLのままです。したがって、明らかに、イベントFocusedNode内からツリーを再ロードして割り当てることはできません。OnNewText

新しいツリーをリロードして再割り当てするための遅延呼び出しを実装しましFocusedNodeた-迅速でダーティなタイマーを実装することで(遅延関数呼び出しにPostMessageを使用できたかもしれませんが、これは単なるばかげた例です)-タイマー内で割り当てた後、それはもはやNULLではなく、期待どおりに機能します。

ツリーのリロードを実装するための最適な方法を誰かに教えてもらえますか?たとえば、新しく設定しても安全でFocusedNode、NULLに再割り当てされない特定のイベントを使用できますか?これを達成する唯一の方法は遅延関数呼び出しですか、それともトラップするためのより良いイベントがありますか(たとえば、OnNewTextこれがフォーカスされたノードの設定を許可しない場合に発生した場合)。もちろんこれは機能しますが、これを行うためのより良い方法があるかどうか興味があります。

4

1 に答える 1

7

ツリー状態FocusedNodeにあるときは変更できず、イベントを終了するまではその状態になります。それ自体は編集検証用です。編集した値を変更できるイベントです。代わりに、編集が実際に行われた後に発生するイベントを使用する必要があります。したがって、次のC ++ Builder擬似コードに示すように、データベースの更新とツリーの再読み込みをそこに移動します。tsEditingOnNewTextOnNewTextOnEdited

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();
} 
于 2012-10-13T12:28:42.370 に答える