RadTreeView virtualization bug

4 posts, 0 answers
  1. Lauren Nickerson
    Lauren Nickerson avatar
    52 posts
    Member since:
    Jul 2009

    Posted 23 Aug 2010 Link to this post

    When I use the page down key or the mouse wheel to scroll down a virtualized RadTreeView, I get this bug:



    The RadTreeViewItems that disappear are actually null when I get in to debug. Why does this happen? It's causing me a problem where a RadTreeViewItem I'm tracking suddenly disappears from memory, even though I have a few other pointers referencing it, it just goes away.

    Let me know if there is a solution to this.

    Thanks!

    Here's my code:

    XAML:
    <Window x:Class="TreeViewComparison.Window1"
        xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"
        Title="Window1" Height="305" Width="627">
        <Window.Resources>
            <HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding SubItems}">
                <TextBlock Text="{Binding Header}"/>
            </HierarchicalDataTemplate>
     
            <Style TargetType="telerik:RadTreeViewItem">
                <Setter Property="IsExpanded" Value="True"/>
            </Style>
             
        </Window.Resources>
         
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <telerik:RadTreeView x:Name="radTreeView"
                                 Grid.Row="0"
                                 IsVirtualizing="True"
                                 ItemTemplate="{StaticResource ItemTemplate}" />
            <Button x:Name="buttonBreakpoint" Grid.Row="1" Margin="8" Content="Breakpoint" Click="buttonBreakpoint_Click" />
        </Grid>
    </Window>

    C#:

    using System;
    using System.Collections.ObjectModel;
    using System.Windows;
     
    namespace TreeViewComparison
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
     
                this.radTreeView.ItemsSource = GenerateItems();
            }
     
            private ObservableCollection<DataItem> GenerateItems()
            {
                ObservableCollection<DataItem> result = new ObservableCollection<DataItem>();
     
                for (int i = 0; i < 10; i++)
                {
                    DataItem item = new DataItem(String.Format("Item {0}", i));
                    for (int j = 0; j < 100; j++)
                    {
                        item.SubItems.Add(new DataItem(String.Format("Item {0}.{1}", i,j)));
                    }
     
                    result.Add(item);
                }
                return result;
            }
     
            class DataItem
            {
                public DataItem(string header)
                {
                    this.SubItems = new ObservableCollection<DataItem>();
                    this.Header = header;
                }
                public string Header { get; set; }
     
                public ObservableCollection<DataItem> SubItems { get; set; }
            }
             
            private void buttonBreakpoint_Click(object sender, RoutedEventArgs e)
            {
             
            }
        }
    }
  2. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 26 Aug 2010 Link to this post

    Hi Lauren Nickerson,

    When the TreeView is virtualized the TreeViewItems are destroyed and recycled across the TreeView.

    There are few exceptions (focused item, selected item) that are not virtualized but you generally should not hold on to any TreeViewItem since after the user scrolls, this same item may represent a different data object. Alternatively this TreeViewItem may be cleared and become part of a cache (then its item will indeed be null).

    This means that less memory will be used to represent the tree structure but you should not save any containers as variables.

    If you need the container for a particular data item, retrieve it when needed. (via the ContainerForItemRecursive method for example)

    If you reckon that this is not the case in your application and there indeed is an item that goes missing, could you help us reproduce this or send us a project where this happens?

    Kind regards,
    Miroslav
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Lauren Nickerson
    Lauren Nickerson avatar
    52 posts
    Member since:
    Jul 2009

    Posted 07 Sep 2010 Link to this post

    Hello, I'm trying to retrieve the item once it got virtualized with ContainerForItemRecursive method as you recommended:

    'If you need the container for a particular data item, retrieve it when needed. (via the ContainerForItemRecursive method for example)'

    But it doesn't work when the item's parent is collapsed, it returns null in such case. Any workaround for this? I need to get the container even if its parent is collapsed.

    Thanks.
  5. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 13 Sep 2010 Link to this post

    Hi Lauren Nickerson,

    In order to get the item with ContainerFromItemRecursive the item container must exist. In other words, when you are using virtualization this particular item does not exist and that is why you can not obtain it.
    You can take a look at this article from our help in order to get more details on the topic:
    http://www.telerik.com/help/wpf/radtreeview-features-ui-virtualization.html

    If you need to get a particular item container then the virtualization must be disabled. Main idea of virtualization is to reduce the space used by visual elements of tree view. Virtualization logic is not able to determine which containers are you going to use in advance.

    I can suggest you to use MVVM pattern and employ ItemContainerStyle when you need to make changes to items while they are out of screen. This way virtualization can do its work by collecting the visual elements. And you will be able to manipulate bound properties of the container through you view model.

    Also you can take a look at http://demos.telerik.com/wpf/ and go to "Controls/NAVIGATION/TreeView/Programatic Expand" for more details.

    Kind regards,
    Hristo Milyakov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top