|
Delphi2010 ツリービュー(TreeView) 2010/10/17 |
まず最初に、「テスト17」(フォルダ「017」)として新規作成しておきます。前回は[Win32]内の「MonthCalendar」(日付カレンダー)について見ましたので、今回は同じく[Win32]内の「TreeView」(ツリービュー)について見てみます。ツリービューは Delphi6 にもあります。
ツリービューを配置してみます。1つ目ですので Nameプロパティは「TreeView1」となります。
ツリービューは木構造(ツリー構造)を表現するコンポーネントで、例えば、文書の索引(インデックス)の構造表現や、フォルダ階層を表現するのに利用する事が出来ます。リストボックス(ListBox)と扱いは少し似ているかもしれませんが、階層化出来るのが大きな違いです。
取り合えず、エディット1つとボタン1つを追加します。エディットに名前を入力してボタンを押すとツリービュー TreeView1にその名前を追加するようにしてみます。
procedure TForm1.Button1Click(Sender: TObject);
var
s : string ;
begin
s := Edit1.Text ;
TreeView1.Items.Add(nil,s);
end; |
この状態で、保存・コンパイル(再構築)・実行を行ってみます。
「あいうえお」と入力してボタンクリック
↓
「かきくけこ」と入力してボタンクリック
↓
「さしすせそ」と入力してボタンクリック
TreeView1に項目が追加されるのが分かります。リストボックスとは異なり、項目の前に線が見えています。この線は ShowLinesプロパティを「True」(デフォルト)から「False」にする事で消す事が出来ます。が、最初はデフォルト状態のままにしておきます。
実行時に項目を追加するのではなく、画面デザイン時に項目を追加しておくことも出来ます。<フォームデザイナ>で TreeView1をダブルクリックするか、或いは、右クリックメニュー「項目の設定」を行います。すると「ツリービュー項目の設定」画面が表示され、項目を追加する事が出来ます。文書のインデックスのように、文書が既に完成されていてそのインデックスも確定しているような場合は、画面デザイン時でも作成できる場合も多いですが、フォルダ表現をしたい場合には、画面デザイン時には分からない・仮に分かっても数が多いと手入力するのが手間である、という事で実行時にプログラムでやってもらう方がいいという場合も多いです。
↓
リストボックスをクリックした場合は、ListBox1.ItemIndexプロパティ値でその位置分かり、その内容は、ListBox1.Items[idx]プロパティで取得できました。それではツリービューの場合はどうなのか?というと、残念ながら ItemIndexプロパティはありませんが、Selectedプロパティがあります。TTreeNode型の値を取得できます。リストボックスの場合は単なる文字列でしたが、ツリービューの場合は、各項目が階層状態等の複数情報を持っているのでオブジェクトになってます。選択していない場合は nil値となります。まぁ、オブジェクトというと難しく聞こえるかもしれませんが扱いは変数の型と同じように扱えますし、慣れてしまえばどうという事はありません。それではツリービューをクリックした時のイベントハンドラを記述します。
procedure TForm1.TreeView1Click(Sender: TObject);
var
n : TTreeNode ;
begin
n := TreeView1.Selected ;
if (n <> nil) then
Edit1.Text := n.Text
else
Edit1.Text := '' ;
end; |
クリックした項目の内容をエディットに表示しているだけです。保存・コンパイル(再構築)・実行を行ってみます。上記のように3項目を追加してから、ツリービューをクリックしてみます。
↓
このままでは階層表現できていませんので、ボタンをもう1つ追加して、そちらをクリックした時には子項目を追加するようにしてみます。
procedure TForm1.Button2Click(Sender: TObject);
var
n : TTreeNode ;
s : string ;
begin
n := TreeView1.Selected ;
s := Edit1.Text ;
TreeView1.Items.AddChild(n,s);
end; |
指定した項目に子を追加する場合は、AddChildメソッドを利用します。第1引数には親オブジェクトを、第2引数には子の内容項目を指定します。それでは保存・コンパイル(再構築)・実行をしてみます。上記のように3項目を追加してから、ツリービューをクリックして、Edit1で入力を行い[子追加]ボタンをクリックします。
「あいうえお」の下に子を追加したい
↓
「ABCDE」と入力して[子追加]をクリック
↓
「あいうえお」の前に三角マークがついた
↓
三角マークをクリックして中身を開くと
子が追加されたのが確認できる
Button1をクリックした時には、Addメソッドを実行していました。この場合は、子を追加しているのではなく、兄弟を追加しているって事になります。「TreeView1.Items.Add(nil,s);」の第1引数は兄のオブジェクトを指定し、第2引数は弟の内容項目を指定します。兄が居ない場合に「nil」を指定していた訳です。少し書き換えます。
procedure TForm1.Button1Click(Sender: TObject);
var
n : TTreeNode ;
s : string ;
begin
n := TreeView1.Selected ;
s := Edit1.Text ;
TreeView1.Items.Add(n,s);
end; |
このようにしておけば子を追加したあと、同じ親から更に子を追加する事も出来ますが、兄を指定してその弟を追加する事も出来るようになります。
弟を作るのではなく、兄を作りたい場合は、Insertメソッドを利用します。
procedure TForm1.Button3Click(Sender: TObject);
var
n : TTreeNode ;
s : string ;
begin
n := TreeView1.Selected ;
s := Edit1.Text ;
TreeView1.Items.Insert(n,s);
end; |
弟となる項目を選択した状態で実行します。nil値の場合は、弟追加のAddメソッドと同じになります。insertは読んで字のごとく、指定した位置に項目を挿入する、という事です。但しこの兄・弟の関係は、並び替えを行うと意味がなくなってしまいますので注意して下さい。
次に、どういう風に内容項目が入るのかを確認するため、[リスト表示]ボタンを追加し、下記のように記述します。各項目は Itemsプロパティに入ります。
procedure TForm1.Button4Click(Sender: TObject);
var
s : string ;
i : integer ;
begin
s := '';
for i:=0 to TreeView1.Items.Count-1 do
s := s + TreeView1.Items[i].Text + #13 + #10 ;
ShowMessage(s);
end; |
保存・コンパイル(再構築)・実行を行います。
テキトウに入力して[リスト表示]
↓
という風に、全て展開した状態での並びとなっているのが分かります。それでは、同じ階層のものを取得したい場合は、どうするかといえば、例えば、各項目の Levelプロパティを取得する方法があります。何階層目かを数値で取得出来ます(一番上の階層は「0」)。上記のイベントハンドラを
procedure TForm1.Button4Click(Sender: TObject);
var
s : string ;
i,lv : integer ;
begin
s := '';
for i:=0 to TreeView1.Items.Count-1 do begin
lv := TreeView1.Items[i].Level ;
s := s + TreeView1.Items[i].Text + ' (' + IntToStr(lv) + ')' + #13 + #10 ;
end;
ShowMessage(s);
end; |
と書き換えて保存・コンパイル・実行をすると以下のようになります。
↓
また、親オブジェクトの GetFirstChildメソッド(最初の子ノードを返す)、GetNextChildメソッド(次の子ノードを返す)、GetPrevChildメソッド(前の子ノードを返す)、GetLastChildメソッド(最後の子ノードを返す)を使う手法、また、兄弟関係を取得する、GetNextSiblingメソッド(呼び出し側ノードと同じレベルにあるツリービュー内の次のノードを返す)、GetPrevSiblingメソッド(呼び出し側ノードの1つ前の同じレベルのノードを返す)、などのメソッドを利用して相対的なオブジェクトを取得する事が出来るようになります。子オブジェクトから親オブジェクトを知りたい場合は、Parentプロパティで分かります。
なお、オブジェクトを削除する場合は、Deleteメソッドを利用します。例えば下記のようにします。
procedure TForm1.Button5Click(Sender: TObject);
var
n : TTreeNode ;
begin
n := TreeView1.Selected ;
if (n <> nil) then
n.Delete ;
end; |
子を持っている場合には、その子も、更に孫も、削除されます。子を持っている場合には削除させない等のような場合には、HasChildrenプロパティ値を調べて判断させます。
procedure TForm1.Button5Click(Sender: TObject);
var
n : TTreeNode ;
begin
n := TreeView1.Selected ;
if (n <> nil) then
if not(n.HasChildren) then
n.Delete
else
ShowMessage('子を持っているので削除できません');
end; |
リストボックス同様、ツリービューにも、内容項目をテキストファイルとして保存・呼び出しするメソッドが搭載されています。保存は恒例のように、SaveToFileメソッド、呼び出しも同様、LoadFromFileメソッドです。
それでは、<オブジェクトプロパティ>を見ていきます。
Alignプロパティはもういつもの定番・お約束です。画面の4辺/全てにくっつける、或いは、何もしない(alNone)を指定します。
AutoExpandプロパティは、Trueにすると(デフォルトは「False」)項目をクリックして選択をするとそれを展開したり(Falseの場合はダブルクリックして意図的に展開させる)、直前に選択していた項目を自動的に折り畳んだり(Falseの場合は意図的に折り畳まない限りはそのまま)します。これは状況や好みによって違うかもしれないですね。
子を追加した時に、その項目(ノード)を展開した状態にしたい場合は、その項目のExpandedプロパティを True にする事で可能になります。
ChangeDelayプロパティは、項目(ノード)を選択してから、OnChangeイベントが発生する間の遅延時間をミリ秒で示します。
HotTrackプロパティは、ツリービューの項目の上をマウスが通過したときに項目を強調表示するかどうかを指定します。デフォルトは「False」で何もしませんが、「True」にすると、以下のように、Windows7では薄っすらと四角が表示されます。
| → | |
Imagesプロパティは、恒例のように、どのイメージリストをツリービューに関連付けるかを示し、各項目(ノード)のイメージは、ImageIndexプロパティ(現在選択されていない場合のイメージ番号)、SelectedIndexプロパティ(現在選択されている場合のイメージ番号)、ExpandedImageIndexプロパティ(項目が展開されているときのイメージ番号)、を指定します。
StateImagesプロパティは、状態イメージに使用するイメージリストを指定し、上記の項目のアイコンの左側に追加イメージとして表示されます。つまりアイコンを2つ付けることが出来ます。その追加アイコンは各項目(ノード)の StateIndexプロパティで、1〜15の番号で示します。0値または-1値の場合はアイコン無しとなります。
Indentプロパティは、子の項目(ノード)を展開した時のインデント幅(見易くするため文字をずらして表示させる量)をピクセル単位で指定します。
MultiSelectプロパティを「True」にすると(デフォルトは「False」:選択は1項目のみ)、複数の項目(ノード)を選択する事が出来るようになります。この場合、選択したかどうかは、各項目(Itemsプロパティ)のSelectedプロパティが「True」か「False」かを調べる事によって、選択されているかされていないかを取得します。また、Selectionsプロパティ・SelectionCountプロパティを利用する事も可能です。
複数選択する場合、MultiSelectStyleプロパティによってどのように選択するかを指定する事が出来ます。以下、ヘルプより。
msControlSelect | 〔Ctrl〕キーを押しながらノードをクリックすると,そのノードの選択および選択解除が切り替わる |
msShiftSelect | 〔Shift〕キーを押しながらノードをクリックし,別のノードを選択すると,その間のノードがすべて選択される。ほかのノードは選択されない |
msVisibleOnly | 〔Shift〕キーによる複数選択に,閉じたノードの子ノードは含まれない |
msSiblingOnly | 選択したノードは,兄弟ノードに限られる |
ReadOnlyプロパティは、ツリービュー上で項目内容の編集を出来るようにするかどうかを指定します。項目内容の編集は、項目を2回クリックする事で、反転表示状態となり、内容を編集することが出来ます。「False」は編集可能状態(デフォルト)で「True」は編集不可な状態となります。
RowSelectプロパティは、ShowLinesプロパティが「False」の場合、選択した項目の行全体を強調表示するかどうかを指定します。「True」であれば行全体を強調表示、「False」であればインデント分を除く文字部分のみ強調表示、です。
ShowButtonsプロパティは、各親項目の左側に正符号[+]と負符号[-]のボタン(※Windows7・Aero状態では三角マーク)を表示するかどうかを指定します。子項目を展開しているかどうかを示すのにも利用されています。これをクリックする事によって展開・折り畳みを指定する事も出来ます。
ShowRootプロパティは、上位レベルにあるノードをつなぐ線を表示するかどうかを指定します。「True」(デフォルト)にする場合は、ShowLinesプロパティも「True」(デフォルト)にします。
こんな感じでしょうか?
そのほか、<オブジェクトインスペクタ>をざっと見る限りにおいては、それ以外については、他のコンポーネントと同様ですので省略します。
ツリービューの機能は結構多いですので、ツリービューを使いこなすには少し慣れが必要かもしれません。親子関係もありますし、各項目のポインタ型のDataプロパティも入ってくると少しややこしいかもしれませんが、最初はシンプルに考えて作りこんでいくのがいいかもしれません。
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
▲2010/10/11
2010/10/17
▼2010/10/18
シェアウェア
Script!World
データベース
|