如何在树视图(WPF)中获取面板

时间:2010-05-20 19:39:09

标签: wpf treeview itemscontrol itemspanel virtualizingstackpanel

如何获得TreeView内使用的面板?我已经读过,默认情况下TreeView会使用VirtualizingStackPanel。当我查看TreeView模板时,我看到的只是< ItemsPresenter />,这似乎隐藏了使用哪个面板的详细信息。

可能的解决方案:

1)在树视图实例(“tv”)上,从代码中执行此操作:tv.ItemsPanel。

问题是,这不会返回一个面板,而是一个ItemsPanelTemplate(“获取或设置定义控制项目布局的面板的模板”。)

2)制作一个明确替换< ItemsPresenter />的TreeView模板使用您自己的ItemsControl.ItemsPanel。我总是提供一个特殊的模板,所以在我的场景中这很好。然后为您放置在该模板中的面板提供零件名称,并从代码中获取该零件(即面板)。这有问题吗?见下文。

(我正在使用一个名为VirtualTreeView的控件,它是从TreeView派生的,如下所示):

<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布局机制。实际上,即使你有TreeViewItems填充树,你只是得到一个空白屏幕。好吧,我想要掌握面板的原因是在MeaureOverride中采用一些部分,但是没有进入所有这些,我当然不想重写如何布局的书树视图。即,这样做的步骤#2方式似乎使得即使使用TreeView也无效。

对不起,如果这里有一些混乱,感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:0)

有一个名为VisualTreeHelper的类,允许您获取控件的未公开子控件/元素。

以下是该类GetChild方法的链接,允许您枚举所有子项等:

http://msdn.microsoft.com/en-us/library/system.windows.media.visualtreehelper.getchild.aspx

答案 1 :(得分:0)

以下是David对上述答案的补充。这提供了一种通过扩展方法获取UIElement的所有视觉子项的方法。

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();