ども、Norimakiです。
今回は久しぶりにTVirtualTreeViewのお話です。
TVirtualTreeViewにはチェックボックスを表示させることが出来ますが、
データを別途用意してOnGetTextイベントでデータを表示させているような場合、
チェックボックスの描画も表示毎にしてあげなければいけません。
一回表示させた後は放置プレイ。という感じであれば、
ユーザーのチェックオン、オフに任せればいいんですが、
フィルタなどで表示内容を様々に変える必要があるのであれば
別途用意しているデータに基づいてチェックのオン・オフを設定しなければいけません。
では、どのタイミング(イベント)で表示させてあげればよいでしょうか。
まあ、「表示させる」というのは正確な表現ではありませんで、
単に「チェックボックスの状態を設定する」。
というのが正しい表現ではあります。
それを踏まえてどこで設定すればよいか?
ということですが、まぁ、何も考えずに、
OnGetTextイベントでもいいんじゃね?
的に思ったりします。
ただ、OnGetTextって同じノードでもColummごとに呼ばれるんですよね。
引数にもColumnがありますから。
で、チェックボックスというのは1つのノードに1つだけですから、
1つのノードで同じ処理を複数回呼ぶのも非効率的かなと。
できることなら1回で済ませたい。
そう思ったりします。
ということで、
OnBeforeItemPaintでどうでしょう?
と思ったりします。
正直良くわかっていないところはありますが、
ここは、アイテムを表示させる直前に呼ばれるはず。
引数にもColumnはないし、1ノード1回かなと。
で、現時点では、ここだろうなと思ったりしています。
正直よくわかりませんし、現代のPCのマシンパワーに頼るならば、
OnGetTextイベントでも良いような気がします。
ただ、個人的には、ちょっとだけ気になるのでOnBeforeItemPaintかなと。
そう思っています。
で、こんな感じで。
1 2 3 4 5 6 7 8 |
procedure TForm1.VirtualStringTree1BeforeItemPaint (Sender: TBaseVirtualTree ;TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect ;var CustomDraw: Boolean); begin if XXXXX[Node.Index].Checked then Node.CheckState:=csCheckedNormal else Node.CheckState:=csUncheckedNormal; end; |
XXXXXはデータを保持しているリストを想定しています。インデックスで操作します。
リストの中身はレコードで、フィールドにCheckedというチェック状態を示すデータを
用意しておき、チェックボックス状態の設定に際して参照します。
1 2 3 4 5 6 7 8 |
type TNYSampleRecord=packed record DataA:string; DataB:string; DataC:string; Checked:boolean; end; |
みたいなレコードをXXXXXというリストに登録しておいて、
Checkedでチェック状態を保持する。
みたいな。
そんな感じでできるんじゃないでしょうか。
また、ユーザーがVirtualTreeViewのチェックのオン・オフを操作したら、
イベントでXXXXX内のデータのCheckedフィールドもそれに応じて変更させる
必要がありますので注意が必要です。
そんな感じです。
ではでは。
Norimakiでした。