ThreadException after drag and drop

3 posts, 1 answers
  1. Wesley
    Wesley avatar
    16 posts
    Member since:
    Jul 2012

    Posted 06 Jul 2012 Link to this post

    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. Answer
    Jack
    Admin
    Jack avatar
    2333 posts

    Posted 11 Jul 2012 Link to this post

    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 >>
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Wesley
    Wesley avatar
    16 posts
    Member since:
    Jul 2012

    Posted 25 Jul 2012 Link to this post

    Hi Jack,

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

    Thanks!
Back to Top