Moving items in a databound collection causes ArgumentOutofRangeException

17 posts, 0 answers
  1. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 18 May 2012 Link to this post

    I have a RadTreeView databound as follows:

    <telerik:RadTreeView Name="LayerTree" HorizontalAlignment="Stretch" 
         ItemsSource="{Binding Path=LayerTviVMList}" 
                                       ContextMenu="{StaticResource LayerTreeContextMenu}"
                                       IsVirtualizing="True" telerik:TreeViewPanel.VirtualizationMode="Recycling"
                                       telerik:AnimationManager.IsAnimationEnabled="False"
                                       SelectionMode="Multiple" BringIntoViewMode="Header" IsLineEnabled="True" ItemsIndent="15" />

    Adding/Removing elements in LayerTviVMList works just fine. 

    I have a collection of 5 elements, and when I do LayerTviVMList.Move(4,0) it appears that RadTreeView is throwing an ArgumentOutOfRangeException.

    Below is the call stack:

      mscorlib.dll!System.ThrowHelper.ThrowArgumentOutOfRangeException() + 0x49 bytes
      mscorlib.dll!System.Collections.Generic.List<System.Windows.UIElement>.this[int].get(int index) + 0x2b bytes
      Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.TreeView.TreeViewPanel.RemoveInternalChildRangeOverride(int startIndex, int count) Line 2863 + 0x13 bytes C#
      Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.TreeView.TreeViewPanel.RemoveChildRange(System.Windows.Controls.Primitives.GeneratorPosition position, int itemCount, int itemUICount) Line 2350 + 0xf bytes C#
      Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.TreeView.TreeViewPanel.OnItemsMove(System.Windows.Controls.Primitives.ItemsChangedEventArgs args) Line 2328 C#
      Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.TreeView.TreeViewPanel.OnItemsChanged(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs args) Line 1821 C#
      PresentationFramework.dll!System.Windows.Controls.VirtualizingPanel.OnItemsChangedInternal(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs args) + 0x36 bytes
      PresentationFramework.dll!System.Windows.Controls.Panel.OnItemsChanged(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs args) + 0x28 bytes
      PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.OnItemMoved(object item, int oldIndex, int newIndex) + 0x35d bytes
      PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x11a bytes
      PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(System.Type managerType, object sender, System.EventArgs e) + 0x5d bytes
      WindowsBase.dll!System.Windows.WeakEventManager.DeliverEventToList(object sender, System.EventArgs args, System.Windows.WeakEventManager.ListenerList list) + 0x5e bytes
      WindowsBase.dll!System.Windows.WeakEventManager.DeliverEvent(object sender, System.EventArgs args) + 0xd7 bytes
      WindowsBase.dll!System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0xa bytes
      PresentationFramework.dll!System.Windows.Data.CollectionView.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x29 bytes
      PresentationFramework.dll!System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(System.Type managerType, object sender, System.EventArgs e) + 0xe0 bytes
      WindowsBase.dll!System.Windows.WeakEventManager.DeliverEventToList(object sender, System.EventArgs args, System.Windows.WeakEventManager.ListenerList list) + 0x5e bytes
      WindowsBase.dll!System.Windows.WeakEventManager.DeliverEvent(object sender, System.EventArgs args) + 0xd7 bytes
      WindowsBase.dll!System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0xa bytes
      PresentationFramework.dll!System.Windows.Data.CollectionView.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x29 bytes
      PresentationFramework.dll!System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(System.Collections.Specialized.NotifyCollectionChangedEventArgs args, int adjustedOldIndex, int adjustedNewIndex) + 0x202 bytes
      PresentationFramework.dll!System.Windows.Data.ListCollectionView.ProcessCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x132 bytes
      PresentationFramework.dll!System.Windows.Data.CollectionView.OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x5d bytes
      System.dll!System.Collections.ObjectModel.ReadOnlyObservableCollection<System.__Canon>.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) + 0x19 bytes
      System.dll!System.Collections.ObjectModel.ReadOnlyObservableCollection<System.__Canon>.HandleCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0xe bytes
      System.dll!System.Collections.ObjectModel.ObservableCollection<Overwatch.ELT.AppCommon.Explorer.LayerTviVM>.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0x52 bytes
      System.dll!System.Collections.ObjectModel.ObservableCollection<System.__Canon>.MoveItem(int oldIndex, int newIndex) + 0x87 bytes
      System.dll!System.Collections.ObjectModel.ObservableCollection<System.__Canon>.Move(int oldIndex, int newIndex) + 0xe bytes

  2. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 21 May 2012 Link to this post

    Hello Chris,

    I wasn't able to reproduce this issue. Can you please take a look at the sample I attached and let me know if I'm missing something? Thank you in advance.

    All the best,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. UI for WPF is Visual Studio 2017 Ready
  4. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 07 Jun 2012 Link to this post

    I finally got a chance to take another look at this and I figured out how to reproduce my issue with your sample.

    Change the OnMove function to do two sequential moves and you'll get the exception:

    private void OnMove(object param)
    {
                Items.Move(4, 0);
                Items.Move(4, 0);
    }

    I can't see any reason why this shouldn't work.
  5. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 11 Jun 2012 Link to this post

    Is there any word on this?  It's high priority for us because it's causing crashes in multiple scenarios.
  6. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 11 Jun 2012 Link to this post

    Interestingly, inverting the indices does not cause a crash:

    private void OnMove(object param)
    {
                Items.Move(0, 4);
                Items.Move(0, 4);
    }

  7. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 12 Jun 2012 Link to this post

    Hello Chris,

    First of all, I would like to take our apologies for the caused inconvenience. It turns out this is a bug in the TreeView virtualization panel.
    The virtualization panel keeps a collection of realized items (those items that have generated container). When you call "Move" on your items collection (if the item is realized) a record from the realized containers collection is removed. If the item is going to be realized again (i.e. it is inserted in the visible part of the TreeView) a corresponding record is inserted in the realized containers collection. But the insertion is asynchronous and is happening at later point in time. If you call Move during the interval where item is removed and not still inserted the exception occurs.
    I can offer you two workarounds:
    1) If you do not need TreeView virtualization you could change the items panel and the exception should go away.
    2) If you need TreeView virtualization feature you could try not using the Move method and perform a Remove and Insert instead.

    private void OnMove(object param)
    {
        //Items.Move(4, 0);
        //Items.Move(4, 0);
        var item4 = Items[4];
        Items.RemoveAt(4);
        Items.Insert(0, item4);
         
        var item3 = Items[4];
        Items.RemoveAt(4);
        Items.Insert(0, item3);
    }

    Hope this helps. Please let us know if provided workarounds are not applicable or you have any other issues.

    Greetings,
    Hristo
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  8. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 12 Jun 2012 Link to this post

    Thanks for the reply.

    We absolutely need the virtualization (it's one of the main reasons why we switched to RadTreeView).  The remove/insert may be a viable workaround, but I just hit another crash when we removed all items from the tree and added a new one.  I'm trying to see if I can modify the sample to replicate it.
  9. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 12 Jun 2012 Link to this post

    When do you think you would release a fix for this bug?

    Our application isn't going to be released until August, so it's not urgent but it would be nice to know when we could expect a fix.
  10. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 14 Jun 2012 Link to this post

    Hello Chris,

    We are currently looking into this issue but it seems that it will require an extensive research and at this point we are not sure if we will be able to find and/or implement a fix. This is why I logged the item in our PITS where you can track its progress. We will update the description/status of the item if we manage to find a fix or a better workaround.

    Greetings,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  11. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 20 Jun 2012 Link to this post

    Update:  The crashes related to removing & adding nodes turned out to be a bug in our own code.  Move is still an issue.

    Is there any way that I can make sequential Move operations wait for the virtualized panel to update its collection of realized items?
  12. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 25 Jun 2012 Link to this post

    Hello Chris,

    The only approach I managed to get working is to delay the call to second (consequent) Move(). The easiest way to do that is to use a dispatcher. However having a visual in the view model is not considered a best practice, but I suppose you could isolate it some part of the view model. I'm attaching a sample solution demonstrating the workaround. Give it a try a check if it does work in your case.

    private void OnMove(object param)
    {
        Items.Move(10, 2);
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            Items.Move(10, 2);
        }), System.Windows.Threading.DispatcherPriority.Background);
    }

    The other workaround is to use Remove and Insert operations. I didn't manage to grasp if this approach is fitting your case.

    Hope this helps. Please let us know if the suggested workaround is not working or not applicable to your case.

    Regards,
    Hristo
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  13. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 27 Jun 2012 Link to this post

    Using the dispatcher worked, thanks.
  14. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 07 Aug 2012 Link to this post

    Is there any word on this issue?

    Dispatching sometimes works, but it's a huge juggling act to dispatch all of our additions/removals to background priority.

    This is making development really challenging for us because when we hit an exception it takes quite a bit of troubleshooting to figure out if it's the tree control or our own code causing the problem.

  15. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 07 Aug 2012 Link to this post

    Hello Chris,

    We did an extensive research on this issue but with the current implementation of the virtualization logic of the RadTreeView, we weren't able to find a fix. This means that in order to fix this issue we'll have to implement serious changes in the internal logic of the control. Unfortunately at this point we cannot schedule such a time-consuming task and this is why I wanted to ask you if you can try the approach using Remove and Insert operations instead of the Move operation. Please let us know if this is a viable workaround for you.

    Regards,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  16. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 07 Aug 2012 Link to this post

    Add/Remove/Insert operations can all trigger the same crash as Move.  It just depends on timing & order of operations.

    We're working around it by dispatching with a background priority but asynchronous code is generally more challenging to get right than synchronous code.
  17. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 08 Aug 2012 Link to this post

    Hello Chris,

    We raised the priority of the issue and we will do our best to provide a fix with the Q3 2012 release. You can track the PITS item for more information on its progress.

    Kind regards,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  18. Chris
    Chris avatar
    30 posts
    Member since:
    Oct 2010

    Posted 08 Aug 2012 Link to this post

    Thank you!
Back to Top
UI for WPF is Visual Studio 2017 Ready