【问题标题】:How to obtain the panel within a treeview (WPF)如何在树视图(WPF)中获取面板
【发布时间】:2010-05-20 19:39:09
【问题描述】:

如何获得TreeView 中使用的面板?我读过默认情况下TreeView 使用VirtualizingStackPanel。当我查看TreeView 模板时,我看到的只是,它似乎隐藏了使用哪个面板的详细信息。

可能的解决方案:

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

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

2) 制作一个 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 的点无效。

抱歉,如果这里有一些混乱,感谢您提供的任何帮助。

【问题讨论】:

    标签: wpf treeview itemscontrol itemspanel virtualizingstackpanel


    【解决方案1】:

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

    这是一个指向该类的 GetChild 方法的链接,它允许您枚举所有的孩子,等等:

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

    【讨论】:

    • 这是我直接要求的,非常感谢。不幸的是,我所追求的更大的事情并没有由此解决,也就是说,我试图在该面板上使用 MeasureOverride。我想我将不得不派生一个面板来覆盖一个方法。不幸的是,这将我带到了第 2 步,TreeView 似乎根本没有自己进行任何渲染(空屏幕)。不过再次感谢。我重新编写了您提供的代码,并正在寻找一种发布方式,这可能对其他人有帮助。
    【解决方案2】:

    以下是对上面大卫给出的答案的补充。这提供了一种通过扩展方法获取所有 UIElements 的 Visual Children 的方法。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2013-08-14
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      相关资源
      最近更新 更多