Basic Library for WPF/Silverlight
ロードオンデマンド
製品の概要 > TreeView > ツリービューの機能 > ロードオンデマンド

アプリケーションの起動時に各ノードをすべて生成するのではなく、ユーザーがノードを展開すると、オンデマンドでノードにデータが挿入される「遅延ロード」という技術を使用することができます。これにより、アプリケーションの読み込み速度が向上し、リソースを効率よく使用できます。

この実装は、ユーザーがノードを展開しようとしたときに、ノードにデータを挿入できるように、Expanding イベントのイベントハンドラを登録します。Tag プロパティには、ノードにデータを挿入するために必要な情報を保存します。最後に、ユーザーがこのノードを展開して、ノードにデータを挿入する Expanding イベントをトリガできるように、ダミーの子ノードを追加します。

メモ: Tag プロパティを使用する代わりに、C1TreeViewItem からカスタムクラスを継承し、そのクラスにすべての遅延ロードロジックを組み込むこともできるはずです。その方が洗練された方法ですが、あいにく WPF ではテンプレートの継承がサポートされていません。テンプレートを持つクラス(ButtonC1TreeViewItem など)からクラスを継承しても、テンプレートは継承されないため、テンプレートを各自で提供する必要があります。そうしないと、その派生クラスは単に空のコントロールになります。

ノードの遅延ロードを実装するには、次のコードを使用します。

C#
コードのコピー
public Page()
{
    InitializeComponent();
    // ここは変更しません
    // ...
    // C1TreeView を初期化します
    InitializeTreeView();
}
void InitializeTreeView()
{
  // 設計時に追加された項目を削除します
  _tv.Items.Clear();
 
   // アセンブリ内のすべての型をスキャンします
  foreach (Type t in _tv.GetType().Assembly.GetTypes())
  {
    if (t.IsPublic && !t.IsSpecialName && !t.IsAbstract)
    {
      // この型のノードを追加します
      C1TreeViewItem node = new C1TreeViewItem();
      node.Header = t.Name;
      node.FontWeight = FontWeights.Bold;
      _tv.Items.Add(node);
      // プロパティ、イベント、およびメソッドのサブノードを追加します
      node.Items.Add(CreateMemberNode("Properties", t, MemberTypes.Property));
      node.Items.Add(CreateMemberNode("Events", t, MemberTypes.Event));
      node.Items.Add(CreateMemberNode("Methods", t, MemberTypes.Method));
    }
  }
}
C1TreeViewItem CreateMemberNode(string header, MemberTypes memberTypes)
{
  // ノードを作成します
  C1TreeViewItem node = new C1TreeViewItem();
  node.Header = header;
  node.Foreground = new SolidColorBrush(Colors.DarkGray);
   // ノードを展開する前にノードにデータを挿入するためのイベントハンドラを登録します
  node.Expanding += node_Expanding;
   // ノードにデータを挿入するために必要な情報を保存します
  node.Tag = memberTypes;
   // このノードを展開できるように、ダミーノードを追加します
  node.Items.Add(new C1TreeViewItem());
  node.IsExpanded = false;
   // 終了します
  return node;
}
//ノードにデータを挿入します
void node_Expanding(object sender, RoutedEventArgs e)
{
  // イベントが発生したノードを取得します
  C1TreeViewItem node = sender as C1TreeViewItem;
  // イベントハンドラの登録を解除します(ノードにデータを挿入したら、このハンドラは不要になります)
  node.Expanding -= node_Expanding;
   // ダミーノードを削除します
  node.Items.Clear();
   // ノードにデータを挿入します
  Type type = (Type)node.Parent.Tag;
  MemberTypes memberTypes = (MemberTypes)node.Tag;
   BindingFlags bf = BindingFlags.Public | BindingFlags.Instance;
  foreach (MemberInfo mi in type.GetMembers(bf))
  {
    if (mi.MemberType == memberTypes)
    {
      if (!mi.Name.StartsWith("get_") && !mi.Name.StartsWith("set_"))
      {
        C1TreeViewItem item = new C1TreeViewItem();
        item.Header = mi.Name;
        item.FontSize = 12;
        node.Items.Add(item);
      }
    }
  }
}