ツリービュー内でパネルを取得する方法(WPF)
-
03-10-2019 - |
質問
どのようにして内部で使用されているパネルを取得できますか TreeView
?デフォルトでそれを読みました TreeView
aを使用します VirtualizingStackPanel
このため。私が見るとき TreeView
テンプレート、私が見るのはすべてですu003CItemsPresenter />、使用されているパネルの詳細を隠しているようです。
可能な解決策:
1)TreeViewインスタンス( "TV")で、コードから、tv.itemspanelを実行します。
問題は、これはパネルを返すのではなく、itemspanelTemplate(「アイテムのレイアウトを制御するパネルを定義するテンプレートを取得または設定する」)です。
2)明示的に置き換えるTreeViewテンプレートを作成しますu003CItemsPresenter />あなた自身のitemscontrol.itemspanelを使用してください。とにかく特別なテンプレートを提供しているので、これは私のシナリオでは問題ありません。次に、そのテンプレート内に配置するパネルに部品名を付け、コードからそのパート(つまり、パネル)を取得できます。これに関する問題は?下記参照。
(以下に示すように、TreeViewから派生したVirtualTreeViewという名前のコントロールを使用しています):
<ControlTemplate x:Key="VirtualTreeViewTemplate" TargetType="{x:Type local:VirtualTreeView}">
<Border>
<local:VirtualScrollViewer
Style="{StaticResource VirtualScrollViewer}"
x:Name="PART_VirtualScrollViewer"
CanContentScroll="True">
<!-- instead of: <ItemsPresenter />, use following: -->
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Name="PART_ItemsStackPanel"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</local:VirtualScrollViewer>
</Border>
</ControlTemplate>
視界のためにここですべての乱雑さを剥ぎ取りました...
これの問題は、これがすぐにTreeViewレイアウトメカニズムをオーバーライドすることです。実際、ツリーを埋めるツリービューイエムがある場合でも、空白の画面を取得するだけです。さて、私がパネルを手に入れたい理由は取ることです いくつかの MeaureOverRideの一部ですが、それすべてに入ることなく、私は確かにツリービューのレイアウト方法の本を書き直したくありません。つまり、これを行うと、ステップ#2の方法は、そもそもツリービューを使用することさえポイントを無効にしているようです。
ここで混乱がある場合は申し訳ありませんが、提供できるヘルプに感謝します。
解決
呼ばれるクラスがあります VisualTreeHelper
これにより、露出していない子供のコントロール/コントロールの要素を取得できます。
これが次のリンクです GetChild
すべての子供を列挙できるようにするクラスの方法:
http://msdn.microsoft.com/en-us/library/system.windows.media.visualtreehelper.getchild.aspx
他のヒント
以下は、上記のDavidが与えた答えの補足です。これは、すべての視覚的な子供を得る方法を提供します UIElement
s拡張法を介してs。
public static class WPFXtensions
{
static public IEnumerable<UIElement> GetDescendantUIElements(this UIElement uiElement)
{
int childrenCnt = VisualTreeHelper.GetChildrenCount(uiElement);
for (int i = 0; i < childrenCnt; i++)
{
Visual childVisual = VisualTreeHelper.GetChild(uiElement, i) as Visual;
if(childVisual == null)
continue;
if (childVisual is UIElement)
{
yield return childVisual as UIElement;
// note: by recursively calling within the loop, we walk the tree all the way down for each
// UIElement encountered before moving to the next UIElement sibling.
foreach (UIElement e in GetDescendantUIElements(childVisual as UIElement))
yield return e;
}
}
}
}
// Use this then like this to retrieve an expected child StackPanel
StackPanel sp1 = (StackPanel)this.GetDescendantUIElements()
.First(uiElem => uiElem is StackPanel);
// Get all of this UIElement's descendants (for a diagnostic look);
// In a run where this was a TreeView, 78 UIElements returned
List<UIElement> uiElements = this.GetDescendantUIElements().ToList();