要素間の移動
要素間の移動はコピーの操作とほとんど変わりません。
ただ、コピーの場合はディープコピーが作成されていましたが、移動の場合は作成されずに要素自体が移動します。
subChildElement.MoveTo( child1Element ); // ツリーの状態 // // Top // Top/Child1 // Top/Child1/SubChild // Top/Child2 //
要素のリンク作成
Windowsにはショートカットやハードリンクなど、要素へのリンクを表す便利な機能があります。CreateLinkElementメソッドを使用して要素自身のリンクを作成すると、これらと同等の機能を実現することができます。
作成されたリンクからリンク先のTreeElementを取得したい場合は、Valueプロパティにアクセスします。
TreeElement subChildLinkElement =
subChildElement.CreateLinkElement();
child1Element.Add( subChildLinkElement );
// ツリーの状態
//
// Top
// Top/Child1
// Top/Child1/<Link>SubChild
// Top/Child2
// Top/Child2/SubChild
//
// リンク先の TreeElement を取得する
TreeElement linkReferenceElement =
( TreeElement )subChildLinkElement.Value;
//
// linkReferenceElement.Name == "SubChild"
//
<Link>というプリフィックスがつきます。表示または非表示の切り替えは、
IsVisibleLinkPrefixプロパティで設定できます。foreachの使用
TreeElementクラスは子要素へ簡単にアクセスする手段として、foreachに対応しています。
ChildElementsプロパティやAllChildElementsプロパティの型であるTreeElementCollectionもforeachに対応していますので、配下にあるすべての子要素にforeachでアクセスしたり、子要素にのみアクセスすることなどが簡単に行えます。
// topElement が次のようなツリー構造になっているものとします。 // // Top // Top/Child1 // Top/Child1/SubChild1 // Top/Child1/SubChild2 // Top/Child2 // // TreeElement 自身を使用 foreach ( TreeElement childElement in topElement ) { Console.WriteLine( childElement.FullPath ); } // 自身を含めたすべての要素へアクセス // // Top // Top/Child1 // Top/Child1/SubChild1 // Top/Child1/SubChild2 // Top/Child2 // // ChildElements プロパティを使用 foreach ( TreeElement childElement in topElement.ChildElements ) { Console.WriteLine( childElement.FullPath ); } // 子要素のみへアクセス // // Top/Child1 // Top/Child2 // // AllChildElements プロパティを使用 foreach ( TreeElement childElement in topElement.AllChildElements ) { Console.WriteLine( childElement.FullPath ); } // すべての子要素へアクセス // // Top/Child1 // Top/Child1/SubChild1 // Top/Child1/SubChild2 // Top/Child2 //
TreeElementVisitor

前述したように、TreeElementのみで階層構造をコードで表現しようとすると、読みにくいコードになったり無理が生じたりする場合があります。
このような場合は、概要図のようにTreeElementのツリー構造内を前後に移動しながらアクセスするTreeElementVisitorを利用すると便利です。
TreeElementVisitorはコンストラクタで設定されたTreeElementを開始位置として、MoveNext、MovePreviousメソッドなどで構造内を移動します。現在位置のTreeElementにアクセスするにはCurrentElementプロパティを使用します。
TreeElementVisitorクラスのメンバは次のとおりです。

TreeElementVisitorの使用例
以下にTreeElementVisitorを開始位置とするTreeElementのインスタンスで初期化し、MoveNextメソッドとMovePreviousメソッドで移動しながら現在位置のTreeElementのパスを出力する例を示します。
// 次のようなツリー構造を持つ TreeElement 型の // treeElement という変数が生成されていると仮定します。 // // Top // Top/Child1 // Top/Child2 // Top/Child2/Child21 // Top/Child2/Child21/Child211 // Top/Child2/Child22 // Top/Child3 // Top/Child3/Child31 // // コンストラクタ TreeElementVisitor visitor = new TreeElementVisitor( treeElement ); while( visitor.HasNext ) { // 次の要素へ移動 visitor.MoveNext(); Console.WriteLine( visitor.CurrentElement.FullPath ); } // 出力結果 // // Top/Child1 // Top/Child2 // Top/Child2/Child21 // Top/Child2/Child21/Child211 // Top/Child2/Child22 // Top/Child3 // Top/Child3/Child31 // while( visitor.HasPrevious ) { // 前の要素へ移動 visitor.MovePrevious(); Console.WriteLine( visitor.CurrentElement.FullPath ); } // 出力結果 // // Top/Child3 // Top/Child2/Child22 // Top/Child2/Child21/Child211 // Top/Child2/Child21 // Top/Child2 // Top/Child1 // Top //
出力結果からMoveNextメソッドとMovePreviousメソッドはお互い逆方向の要素へ移動していることが分かると思います。
移動手段としてこれらのメソッド以外にもMove( Int32 ):voidメソッドで数値を指定して前後へ移動したり、MoveUp():voidメソッドで親要素へ移動したり直感的に操作することができるメソッドを用意してあります。
まとめ
今回のTreeElementの使用例では、ツリー構造を分かりやすくするために主にSystem.String型を使用しましたが、ValueプロパティはObject型なので汎用的な型を利用することができることから、.NETFrameworkクラスライブラリのSystem.Collections.ArrayListクラスのように、気軽にツリー構造を持つデータを表現することができます。
詳しい内部処理などは「TreeElementソリューションファイル」内のソースコードをご覧ください。
