This is a migrated thread and some comments may be shown as answers.

ThreadException after drag and drop

2 Answers 107 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Wesley
Top achievements
Rank 1
Wesley asked on 06 Jul 2012, 09:03 AM
Hi,

I have a treeview that shows account numbers in a hierarchy of account groups.
MultiSelect is on for the treeview.
Sometimes (not always), when I drop multiple items on an account group node a thread exception occurs.
I recently upgraded the RadControls from 'Q3 2011 SP1' to 'Q2 2012'. In the older version this problem did not exist. I did not change code, only the Telerik dll changed.

Some more details:

Message = Object reference not set to an instance of an object.
Stacktrace = at Telerik.WinControls.UI.TreeNodeElement.ApplyStyle()
   at Telerik.WinControls.UI.TreeNodeElement.OnPropertyChanged(RadPropertyChangedEventArgs e)
   at Telerik.WinControls.RadObject.RaisePropertyNotifications(RadPropertyValue propVal, Object oldValue, Object newValue, ValueSource oldSource)
   at Telerik.WinControls.RadObject.ResetValueCore(RadPropertyValue propVal, ValueResetFlags flags)
   at Telerik.WinControls.UI.TreeNodeElement.Detach()
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.RemoveElement(Int32 position)
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureElements()
   at Telerik.WinControls.UI.BaseVirtualizedContainer`1.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
   at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
   at Telerik.WinControls.UI.ScrollViewElement`1.MeasureViewElement(SizeF availableSize)
   at Telerik.WinControls.UI.ScrollViewElement`1.MeasureView(SizeF availableSize)
   at Telerik.WinControls.UI.ScrollViewElement`1.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.UI.VirtualizedScrollPanel`2.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.RadElement.MeasureCore(SizeF availableSize)
   at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
   at Telerik.WinControls.RootRadElement.MeasureOverride(SizeF availableSize)
   at Telerik.WinControls.RootRadElement.MeasureCore(SizeF availableSize)
   at Telerik.WinControls.RadElement.Measure(SizeF availableSize)
   at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout()
   at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayoutCallback(ILayoutManager manager).

Relevant code:

public partial class AccountGroupList : AccountsFormBase
    {
        public AccountGroupList()
        {
            InitializeComponent();
 
            accountGroupTreeView.NodeMouseDown += AccountGroupTreeViewNodeMouseDown;
            accountGroupTreeView.DragStarting += AccountGroupTreeViewDragStarting;
            accountGroupTreeView.DragOverNode += AccountGroupTreeViewDragOverNode;
            accountGroupTreeView.DragEnding += AccountGroupTreeViewDragEnding;
            accountGroupTreeView.ContextMenuStrip = contextMenuStrip;
            accountGroupTreeView.AllowDragDrop = true;
            accountGroupTreeView.MultiSelect = true;
        }
 
        protected override void OnDataBind()
        {
            FillAccountGroupTreeView();
        }
 
        private void FillAccountGroupTreeView()
        {
            accountGroupTreeView.Nodes.Clear();
             
 
            //find and add main account groups to tree
            foreach (AccountOrAccountGroupInfo mainAccountGroup in Model.AccountGroupHierarchy.Where(x => !x.EreportingId.HasValue && !x.ParentId.HasValue))
            {        
                var mainAccountGroupNode = new AccountGroupNode(mainAccountGroup.AccountGroup, true) {Tag = mainAccountGroup};
 
                //find and add sub account groups of main account group
                foreach (AccountOrAccountGroupInfo subAccountGroup in Model.AccountGroupHierarchy.Where(x => !x.EreportingId.HasValue && x.ParentId == mainAccountGroup.Id))
                {
                    var subAccountNode = new AccountGroupNode(subAccountGroup.AccountGroup, false) { Tag = subAccountGroup };
 
                    //find and add ereporting accounts of sub account group
                    foreach (AccountOrAccountGroupInfo eReportingAccount in Model.AccountGroupHierarchy.Where(x => x.EreportingId.HasValue && x.ParentId == subAccountGroup.Id))
                    {
                        var eReportingAccountNode = new EreportingAccountNode(eReportingAccount.AccountGroup)
                                                        {Tag = eReportingAccount, AllowDrop = false};
                        subAccountNode.Nodes.Add(eReportingAccountNode);   
                    }
 
                    mainAccountGroupNode.Nodes.Add(subAccountNode);  
                }
 
                //find and add ereporting accounts of main account group
                foreach (AccountOrAccountGroupInfo eReportingAccount in Model.AccountGroupHierarchy.Where(x => x.EreportingId.HasValue && x.ParentId == mainAccountGroup.Id))
                {
                    var eReportingAccountNode = new EreportingAccountNode(eReportingAccount.AccountGroup) { Tag = eReportingAccount };
                    mainAccountGroupNode.Nodes.Add(eReportingAccountNode);
                }
 
                accountGroupTreeView.Nodes.Add(mainAccountGroupNode);
            }
 
            //find and add ereporting accounts that are not linked to an account group
            foreach (AccountOrAccountGroupInfo eReportingAccount in Model.AccountGroupHierarchy.Where(x => x.EreportingId.HasValue && !x.ParentId.HasValue))
            {
                var eReportingAccountNode = new EreportingAccountNode(eReportingAccount.AccountGroup) { Tag = eReportingAccount, AllowDrop = false };
 
                accountGroupTreeView.Nodes.Add(eReportingAccountNode);
            }
        }
 
        #region drag, drop, context menu
 
        private void AccountGroupTreeViewDragStarting(object sender, RadTreeViewDragCancelEventArgs e)
        {
            try
            {
                //determine if dragging is allowed for selected node
                if (e.Node != null)
                {
                    //An ereporting account node can be dragged
                    var ereportingAccountNode = e.Node as EreportingAccountNode;
                    if (ereportingAccountNode != null)
                    {
                        e.Cancel = false;
                    }
                    else
                    {
                        //A group node can only be dragged if it has no child groups
                        var accountGroupNode = e.Node as AccountGroupNode;
                        if (accountGroupNode != null)
                        {
                            e.Cancel = (accountGroupNode.SubAccountGroupCount > 0);
                        }
                        else
                        {
                            e.Cancel = true;
                        }
                    }
                }
                else
                {
                    e.Cancel = true;
                }
            }
            catch (Exception)
            {
                e.Cancel = true;   
                throw;
            }
             
        }
 
        private void AccountGroupTreeViewDragOverNode(object sender, RadTreeViewDragCancelEventArgs e)
        {
            try
            {
                //determine if the dragged node can be dropped on the current hovered node
                if (e.Node != null)
                {
                    var accountNode = e.Node as AccountNodeBase;
                    if (accountNode != null)
                    {
                        e.Cancel = !(accountNode.CanBeDroppedOnTarget(e.TargetNode));
                    }
                    else
                    {
                        e.Cancel = true;
                    }
                }
                else
                {
                    e.Cancel = true;
                }
            }
            catch (Exception)
            {
                e.Cancel = true;   
                throw;
            }
             
         
        }
 
        private void AccountGroupTreeViewDragEnding(object sender, RadTreeViewDragCancelEventArgs e)
        {
            try
            {
                //recheck if it is correct to drop the dragged node on the target node (this event is fired multiple times when multiple nodes are dragged at once)
                //execute the action that is expected
                var accountNode = e.Node as AccountNodeBase;
                if (accountNode != null)
                {
                    if (accountNode.CanBeDroppedOnTarget(e.TargetNode))
                    {
                        var draggedAccountGroupHierarchy = (AccountOrAccountGroupInfo)accountNode.Tag;
                        var targetAccountGroupHierarchy = ((AccountOrAccountGroupInfo)e.TargetNode.Tag);
 
                        if (e.Node is EreportingAccountNode)
                        {
                            Controller.MoveEreportingAccountToAccountGroup(draggedAccountGroupHierarchy.Id, targetAccountGroupHierarchy.Id);
                        }
                        else
                        {
                            Controller.MoveAccountGroupUnderAccountGroup(draggedAccountGroupHierarchy.Id, targetAccountGroupHierarchy.Id);
                        }
                    }
                    else
                    {
                        e.Cancel = true;
                    }
                }
                else
                {
                    e.Cancel = true;
                }   
            }
            catch (Exception)
            {
                e.Cancel = true;   
                throw;
            }
             
        }
 
        #endregion
 
        #region Tree Node classes
 
        private abstract class AccountNodeBase : RadTreeNode
        {
            protected readonly Font TreeNodeFont = new Font("Segoe UI", 8.25f);
            public abstract bool CanBeDroppedOnTarget(RadTreeNode target);
        }
 
        private class AccountGroupNode : AccountNodeBase
        {
            public bool IsRootNode { get; private set; }
 
            public int SubAccountGroupCount
            {
                get { return Nodes.Count(o => o is AccountGroupNode); }
            }
 
            internal AccountGroupNode(string text, bool isRootNode)
            {
                Font = TreeNodeFont;
                Text = text;
                IsRootNode = isRootNode;
            }
 
            public override bool CanBeDroppedOnTarget(RadTreeNode target)
            {
                //a group node can be dropped on target if
                // -the target is also a group node
                // -the node has no child groups
                // -the node is a main group (level 1)
                // -the target node is not the current parent of the node
                var targetNode = target as AccountGroupNode;
                return targetNode != null && SubAccountGroupCount == 0 && targetNode.IsRootNode && targetNode != Parent;
            }
        }
 
        private class EreportingAccountNode : AccountNodeBase
        {
            internal EreportingAccountNode(string text)
            {
                Font = TreeNodeFont;
                Text = text;
            }
 
            public override bool CanBeDroppedOnTarget(RadTreeNode target)
            {
                //an ereporting node can be dropped on any group node that is not the current parent of the ereporting node
                if (!(target is EreportingAccountNode) && target != Parent)
                {
                    return true;
                }
                return false;
            }
        }
        #endregion
    }

2 Answers, 1 is accepted

Sort by
0
Accepted
Jack
Telerik team
answered on 11 Jul 2012, 10:49 AM
Hello Wesley,

I was not able to compile and test the provided code. However, it looks OK and I did not find anything suspicious. We identified a similar issue in our new theme engine which we introduced in our latest release - Q2 2012. It is addressed in our latest internal build. You can download it from your client account and give it a try. 

If the issue still appears, please send us a working solution where we can reproduce it.

I am looking forward to your reply.

Kind regards,
Jack
the Telerik team
RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
0
Wesley
Top achievements
Rank 1
answered on 25 Jul 2012, 08:38 AM
Hi Jack,

Using the dll's of the latest internal build did the trick.

Thanks!
Tags
Treeview
Asked by
Wesley
Top achievements
Rank 1
Answers by
Jack
Telerik team
Wesley
Top achievements
Rank 1
Share this question
or