简体   繁体   English

WPF TreeView和虚拟化问题

[英]WPF TreeView and Virtualization issue

I have a TreeView with 2 level Hierarchy. 我有一个具有2级层次结构的TreeView。 TreeView Item has got biding to the property of particular class. TreeView项目已经绑定到特定类的属性。 Basically I am getting the ObservableCollection list and assiging that list as my TreeView ItemsSource. 基本上我得到ObservableCollection列表并将该列表指定为我的TreeView ItemsSource。 Initially treeView visibility set to Collapsed and after assigning the ItemsSource, TreeView visibility set to Visible. 最初将treeView可见性设置为Collapsed,并在分配ItemsSource后,将TreeView可见性设置为Visible。 At this point app freezes for about 40 secs (Its basically loading 1000s of parent item and 5-10 children for each parent). 此时app冻结了大约40秒(它基本上加载了1000个父项,每个父项加了5-10个孩子)。

Code behinnd is 代码behinnd是

PopulateTreeView()
{
    // ocListToDisplay is my ObservableCollection
    tvES.ItemsSource = ocListToDisplay;

    //App Freezes at this bit when making the tvES Visible from Collapsed
    tvES.Visibility = System.Windows.Visibility.Visible; 
}

My XAML is like this 我的XAML是这样的

 <ScrollViewer Name="scContainer" VerticalAlignment="Stretch" 
               HorizontalAlignment="Stretch">
    <StackPanel>
        <StackPanel.Resources>
            <exportImport:TreeViewDashboard x:Key="dataItems"/>
            <HierarchicalDataTemplate DataType="{x:Type exportImport:TreeViewDashboard}"
                                      ItemsSource="{Binding Path=Components}">

                <Grid  Margin="2" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition ></ColumnDefinition>
                        <ColumnDefinition ></ColumnDefinition>
                        <ColumnDefinition ></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <CheckBox Name="checkbx" Grid.Column="0" Margin="2" 
                              Tag="{Binding Path=Tag}" 
                              Checked="OnCheck" Unchecked="OnUnCheck"></CheckBox>
                    <Image Margin="2" Grid.Column="1" Source="{Binding Path=ImageUrl}"  
                           Height="14" Width="16" ></Image>
                    <TextBlock Margin="2" Grid.Column="2" Text="{Binding Path=Name}"
                              FontWeight="Bold" />
                </Grid>

                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <Grid  Margin="2" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition ></ColumnDefinition>
                                <ColumnDefinition ></ColumnDefinition>
                                <ColumnDefinition ></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <CheckBox Name="checkbx" Grid.Column="0" Margin="2" 
                                      Tag="{Binding Path=Tag}" 
                                      Checked="OnCheck" Unchecked="OnUnCheck"/>
                            <Image Margin="2" Grid.Column="1" 
                                   Source="{Binding Path=ImageUrl}" 
                                   Height="14" Width="16" />
                            <TextBlock Margin="2" Grid.Column="2" 
                                  Text="{Binding Path=Name}" FontWeight="Bold" />
                        </Grid>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>

            </HierarchicalDataTemplate>
        </StackPanel.Resources>

        <--same result if you set IsVirtualizing to True/False App freezes for 40 sec-->
        <TreeView Name="tvES"  BorderThickness="0" 
              ItemsSource="{Binding Source={StaticResource dataItems}}"
              VirtualizingStackPanel.IsVirtualizing="False"
              VirtualizingStackPanel.VirtualizationMode="Recycling"
              TreeViewItem.Expanded="item_Expanded"
              TreeViewItem.Collapsed="item_Collapsed" >
            <TreeView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </TreeView.ItemsPanel>
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="False" />
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>
    </StackPanel>  
 </ScrollViewer>

I also tried to get the number of visuals in my tree view. 我还尝试在树视图中获取视觉效果的数量。 I get the same number of Visuals count in both the cases of IsVisualizing="True" and IsVisualizing="False" That clearly indicating that I am doing something wrong. IsVisualizing =“True”和IsVisualizing =“False”的情况下,我得到相同数量的Visuals计数,这清楚地表明我做错了。

Code to get visual count from the tree 从树中获取视觉计数的代码

  //In my case I am passing tvES as  DependencyObject
    private static int GetVisualCount(DependencyObject visual)
    {
        int visualCount = 1;
        int childCount = VisualTreeHelper.GetChildrenCount(visual);

        for (int i = 0; i < childCount; i++)
        {
            DependencyObject childVisual = VisualTreeHelper.GetChild(visual, i);
            visualCount += GetVisualCount(childVisual);
        }

        return visualCount;
    } 

I get the treeview eventually but the problem is my app freezes while populating the treeview..!! 我最终得到了树视图,但问题是我的应用程序冻结了填充树视图.. !! Anyone got the workaound for this?? 有人为此得到了工作量吗? I have got scollviewer, will that causing problem to virtualization? 我有scollviewer,这会导致虚拟化问题吗?

PS: TreeView Generated is like this but have 1000's of similar nodes PS:TreeView Generated是这样的,但有1000个类似的节点

在此输入图像描述

Updates : 更新

I was reading about VirtualizingStackPanel where it says - "Virtualization in a StackPanel only occurs when the items control contained in the panel creates its own item containers. You can ensure this happens by using data binding. In scenarios where item containers are created and added to the items control, a VirtualizingStackPanel offers no performance advantage over a StackPanel." 我正在阅读VirtualizingStackPanel,它说 - “StackPanel中的虚拟化只发生在面板中包含的项目控件创建自己的项目容器时。您可以通过使用数据绑定来确保这种情况发生。在创建项目容器并添加到其中的情况下在itemsPanel中,VirtualizingStackPanel没有提供性能优势。“

can someone suggest me if the above approach which i am following is right?? 有人建议我,如果我遵循的上述方法是正确的?? I am pretty much sure that I am I am on wrong side.. 我非常确定我是在错误的一面..

You forgot to set ScrollViewer.CanContentScroll=True . 你忘了设置ScrollViewer.CanContentScroll=True That is a key for virtualization. 这是虚拟化的key And put the IsVirtualizing back to true 并将IsVirtualizing恢复为true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM