TreeListViewRow.ParentRow throws NullReferenceException in Telerik.Windows.Controls.GridView when child collection is null

3 posts, 1 answers
  1. Cale
    Cale avatar
    2 posts
    Member since:
    Feb 2012

    Posted 29 Feb 2012 Link to this post

    This code used to work with an older Telerik release (can verify the version if need be), but no longer works with the latest (RadControls_for_WPF_2012_1_0215_Dev).

    Steps to reproduce:
    1. Right-click and select the context menu item to add a top-level row.
    2. Right-click the row and select the context menu item to add a child row.
    3. Right-click the child row, and you get the exception.

    TreeListViewRow.ParentRow throws an exception because it tries to do "var parentView = this.Items.ParentView;" but Items is null.

    Each top-level (parent) row contains a ParentItem object with a ChildItems property, and the ChildTableDefinition is bound to the ChildItems property. Each child row contains a ChildItem object, which doesn't have a ChildItems property, so when it tries to get the child items for a child row, the collection is null. As a workaround, if I give the ChildItem class a ChildItems property and have it return an empty collection, then the exception goes away. I'm no telerik expert, but it seems strange to me that a row needs to have a non-null collection of child items in order to access the row's parent row.

    Apparently you don't let users upload test projects, so here's the source:

    <Window x:Class="TestTreeListView.MainWindow"
          <CommandBinding Command="local:MainWindow.AddParentRow" Executed="AddParentRow_Executed" />
          <!-- The style of the expand button in the totally rad tree. -->
          <Style x:Key="ExpandButtonStyle" TargetType="{x:Type telerik:GridViewToggleButton}">
             <Setter Property="PresentationMode" Value="PlusMinus"/>
          <!-- Context menu for adding a child row to a parent row. -->
          <ContextMenu x:Key="ParentRowContextMenu">
                <CommandBinding Command="local:MainWindow.AddChildRow" Executed="AddChildRow_Executed" />
             <MenuItem Command="local:MainWindow.AddChildRow" />
          <!-- A sorted view of the totally rad tree items. -->
          <CollectionViewSource x:Key="TotallyRadItemsView"
                                Source="{Binding ElementName=mainWindow, Path=ParentItems}">
                <scm:SortDescription PropertyName="Name" />
          <telerik:RadTreeListView Name="totallyRadTreeListView"
                                   HierarchyExpandButtonStyle="{StaticResource ExpandButtonStyle}"
                                   ItemsSource="{Binding Source={StaticResource TotallyRadItemsView}}">
                <telerik:TreeListViewTableDefinition ItemsSource="{Binding ChildItems}" />
                <!-- Context menu for adding a parent row. -->
                   <MenuItem Command="local:MainWindow.AddParentRow"
                             CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Telerik.Windows.Controls.GridView;     // for RowLoadedEventArgs
    using Telerik.Windows.Controls.TreeListView; // for TreeListViewRow
    namespace TestTreeListView
       /// <summary>
       /// Interaction logic for MainWindow.xaml
       /// </summary>
       public partial class MainWindow : Window
          public MainWindow()
             // RadTreeListView doesn't select its items on right-click, so add
             // an event handler that accomplishes this.
             mTreeItemClickHandler = new MouseButtonEventHandler( TotallyRadTreeListViewRow_MouseRightButtonDown );
             totallyRadTreeListView.RowLoaded += new EventHandler<RowLoadedEventArgs>( TotallyRadTreeListView_RowLoaded );
             totallyRadTreeListView.RowUnloaded += new EventHandler<RowUnloadedEventArgs>( TotallyRadTreeListView_RowUnloaded );
          static MainWindow()
             AddParentRow = new RoutedUICommand( "Add Parent Row", "AddParentRow", typeof( MainWindow ) );
             AddChildRow = new RoutedUICommand( "Add Child Row", "AddChildRow", typeof( MainWindow ) );
          public static RoutedUICommand AddParentRow { get; set; }
          public static RoutedUICommand AddChildRow { get; set; }
          public ObservableCollection<ParentItem> ParentItems { get { return mParentItems; } }
          private void TotallyRadTreeListViewRow_MouseRightButtonDown( object sender, MouseButtonEventArgs e )
             TreeListViewRow row = sender as TreeListViewRow;
             row.IsSelected = true;
             // Throws an exception when right-clicking a child row.
             if ( row.ParentRow != null )
                // use row.ParentRow.Item here
             // Show the context menu whenever a parent row is clicked.
             if ( row.Item is ParentItem )
                ContextMenu menu = FindResource( "ParentRowContextMenu" ) as ContextMenu;
                menu.IsOpen = true;
          private void TotallyRadTreeListView_RowLoaded( object sender, RowLoadedEventArgs e )
             if ( e.Row.Item != null )
                e.Row.MouseRightButtonDown += mTreeItemClickHandler;
          private void TotallyRadTreeListView_RowUnloaded( object sender, RowUnloadedEventArgs e )
             e.Row.MouseRightButtonDown -= mTreeItemClickHandler;
          private void AddParentRow_Executed( object target, ExecutedRoutedEventArgs e )
             mParentItems.Add( new ParentItem() );
          private void AddChildRow_Executed( object target, ExecutedRoutedEventArgs e )
             ParentItem parentItem = totallyRadTreeListView.SelectedItem as ParentItem;
             parentItem.ChildItems.Add( new ChildItem() );
          private MouseButtonEventHandler mTreeItemClickHandler = null;
          ObservableCollection<ParentItem> mParentItems = new ObservableCollection<ParentItem>();
       public class ParentItem
          public string Name { get { return name; } }
          public ObservableCollection<ChildItem> ChildItems { get { return mChildItems; } }
          private string name = "Parent" + i++;
          ObservableCollection<ChildItem> mChildItems = new ObservableCollection<ChildItem>();
          private static int i = 0;
       public class ChildItem
          public string Name { get { return name; } }
          //public ObservableCollection<ChildItem> ChildItems { get { return mChildItems; } }
          private string name = "Child" + i++;
          //ObservableCollection<ChildItem> mChildItems = new ObservableCollection<ChildItem>();
          private static int i = 0;
  2. Answer
    Yordanka avatar
    634 posts

    Posted 01 Mar 2012 Link to this post

    Hello Cale,

    Thank you for the feedback.

    We were able to reproduce the exception and it was resolved immediately. The fix will be part of the next internal build (on Monday).
    Kind regards,
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. Cale
    Cale avatar
    2 posts
    Member since:
    Feb 2012

    Posted 01 Mar 2012 Link to this post

    That was fast! Thanks!
Back to Top