ツリー構造を展開したり折りたたんだりして表示できるTreeViewコントロール。
TreeViewコントロールをマウスクリックで展開させるだけでなく、ある特定の項目まで展開しスクロールして表示させたいケースがあります。
ListViewクラスでは ScrollIntoView というメソッドがあり見える位置まてスクロールして表示してくれる機能がありますが、同様のことを TreeView でも行うにはどのようにすればよいでしょう?
参考:C# WPFのListViewで選択行を見える位置までスクロールする
TreeViewの使い方のおさらい
ここではTreeViewに対してデータをバインディングして使うことを想定しています。
TreeViewへデータをバインドする方法については以下を参照してください。
ItemContainerGeneratorとBringIntoView
TreeViewクラスには ItemContainerGenerator というプロパティがあります。
これをうまく使うことで、ツリーの各項目のUIコントロール(TreeViewItemクラス)を取得することが出来ます。
また、TreeViewItemクラスにはBringIntoViewというメソッドがあり、これを使えばこの項目が表示されるようスクロールしてくれます。
つまり、ItemContainerGenerator で該当のTreeViewItemを見つけ出し、そのTreeViewItemでBringIntoViewメソッドを呼び出せばよいのですが、TreeViewItemの探し方には工夫が必要です。
ItemContainerGenerator は子階層のUIコントロールを制御するもので、孫階層やさらに下の階層のことまで制御してくれません。下の階層まで探すためのコードを書く必要があります。
private void BringIntoTreeView(TreeView view, TreeSource selectedSrc) { var queue = new System.Collections.Generic.Stack<TreeSource>(); var src = selectedSrc; while (null != src) { queue.Push(src); src = src.Parent; } var generator = view.ItemContainerGenerator; while (0 < queue.Count) { src = queue.Pop(); var treeViewItem = (TreeViewItem)generator.ContainerFromItem(src); if (null != treeViewItem) { if (selectedSrc != src) { treeViewItem.IsExpanded = true; } else { treeViewItem.IsSelected = true; treeViewItem.BringIntoView(); } generator = treeViewItem.ItemContainerGenerator; } } }
データ階層を収集(3~9行目)
指定の項目から順に親要素を収集していきます。
親要素から順にTreeViewItemを取得(11~29行目)
最初はTreeViewからItemContainerGeneratorを取得します。
ContainerFromItemメソッドを使うと指定したデータに対応するTreeViewItemを取得できます。
親階層の項目であれば、IsExpandedプロパティを true にしてツリーを展開表示し、さらに下層のコントロールを探すため、TreeViewItemからItemContainerGeneratorを取り直します。
目的の項目であれば、BringIntoViewメソッドを呼び出してスクロールさせます。
コメントをお書きください