NullReferenceException after drop item

4 posts, 1 answers
  1. Miłosz Cechnicki
    Miłosz Cechnicki avatar
    34 posts
    Member since:
    Sep 2009

    Posted 11 Mar 2010 Link to this post

    Hi,

    I try to bind Xml.Linq XEelement to RadTreeView with a Converter. 

    I get NullReferenceException when I drop any node onto another one within the RadTreeView control.

    Below is the XAML code:

    <UserControl x:Class="XmlSample.MainPage"    
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:XmlSample="clr-namespace:XmlSample"        
        xmlns:Telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls"        
        xmlns:TelerikNavigation="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" >        
        <UserControl.Resources>    
     
            <XmlSample:XElementChildrenConverter x:Key="XElementChildrenConverter" />    
                
            <Telerik:HierarchicalDataTemplate x:Key="Element" ItemsSource="{Binding ., Converter={StaticResource XElementChildrenConverter}}" >    
                <TextBlock Text="{Binding Name}" />    
            </Telerik:HierarchicalDataTemplate>      
     
        </UserControl.Resources>    
        <Grid x:Name="LayoutRoot">                
     
            <TelerikNavigation:RadTreeView     
                x:Name="ctrlTree"                 
                IsDragDropEnabled="True"     
                ItemTemplate="{StaticResource Element}"      
                />                
        </Grid>    
    </UserControl>  

    and C# code:

    using System;  
    using System.Windows.Controls;  
    using System.Xml.Linq;  
    using System.Windows.Data;  
     
    namespace XmlSample  
    {  
        public partial class MainPage : UserControl  
        {  
            public MainPage()  
            {  
                InitializeComponent();  
     
                XDocument xdoc = new XDocument();  
                xdoc.Add(new XElement("root"));  
                xdoc.Root.Add(new XElement("node1"));  
                xdoc.Root.Add(new XElement("node2"));  
                xdoc.Root.Add(new XElement("node3"));  
     
                ctrlTree.ItemsSource = xdoc.Elements();  
            }  
        }  
     
        public class XElementChildrenConverter : IValueConverter  
        {  
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
            {  
                if (value is XElement)  
                {  
                    return (value as XElement).Elements();  
                }  
                return null;  
            }  
     
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
            {  
                throw new NotImplementedException();  
            }  
        }  
    }  
     

    Are you going to fix this bug? Is there any workaround to fix the issue?

    Thanks in advice.

    Regards

  2. Answer
    Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 16 Mar 2010 Link to this post

    Hi Miłosz Cechnicki,

    Thank you for reporting this bug. It is logged in our public issue tracking system, its title is:

    TreeView: DragDrop when bound to XML throws a null ref exception

    The Elements() call returns an enumeration (i.e. not a List) and cannot be modified. The TreeView is missing some checks for this and we are going to introduce them - then DragDrop will not be allowed with non-list enumerations.

    Currently I can suggest disabling the DragDrop since it should not work anyway.

    If you want to enable DragDrop I can suggest presenting your XElements in an ObservableCollection and then converting them back to an XML hierarchy when needed.

    Your Telerik Points have been updated for your feedback.

    Best wishes,
    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. Miłosz Cechnicki
    Miłosz Cechnicki avatar
    34 posts
    Member since:
    Sep 2009

    Posted 17 Mar 2010 Link to this post

    Thank you for your answer.

    I've resolved my issue by creating a wrapper class (called it XmlNode) and then binding ItemsSource to XmlNode Children property.

    C#:

    XDocument document = XDocument.Load("sample.xml");

    ctrlTree.ItemsSource = new XmlNode[] { new XmlNode(document.Root) };

    XAML:

    <Telerik:HierarchicalDataTemplate x:Key="XmlNodeTemplate" 

      ItemsSource="{Binding Children}" > 

    XmlNode class:

        public class XmlNode 
        {  
            public XElement Element { getprivate set; }  
     
            public ObservableCollection<XmlNode> Children { getprivate set; }  
     
            public XmlNode(XElement element)  
            {  
                Children = new ObservableCollection<XmlNode>();  
                Element = element;  
                foreach (XElement el in element.Elements())  
                {  
                    Children.Add(new XmlNode(el));  
                }  
                Children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Children_CollectionChanged);  
            }  
     
            void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)  
            {  
                if (e.Action == NotifyCollectionChangedAction.Add)  
                {  
                    int i = 0;  
                    foreach (XElement el in this.Element.Elements())  
                    {  
                        if (i++ == e.NewStartingIndex)  
                        {  
                            foreach (XmlNode xmlNode in e.NewItems)  
                            {  
                                el.AddBeforeSelf(xmlNode.Element);  
                            }  
                            return;  
                        }  
                    }  
                    foreach (XmlNode xmlNode in e.NewItems)  
                    {  
                        this.Element.Add(xmlNode.Element);  
                    }  
                }  
                else if (e.Action == NotifyCollectionChangedAction.Remove)  
                {  
                    foreach (XmlNode xmlNode in e.OldItems)  
                    {  
                        xmlNode.Element.Remove();  
                    }  
                }  
            }  
        } 

    Regards

  4. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 22 Mar 2010 Link to this post

    Hello Miłosz Cechnicki,

    We are glad to hear that the issue is already solved.
    We deeply appreciate your feed back and would like to thank you for the valuable sample code.


    Best wishes,
    Bobi
    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