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

nullreferenceexception when dragging things inside a RadListBox

3 Answers 265 Views
DragAndDrop
This is a migrated thread and some comments may be shown as answers.
Andrey
Top achievements
Rank 1
Andrey asked on 22 Mar 2018, 05:25 PM

So, I have a RadListBox that I have set up to reorder items when the user drags one list box item in between two others. Its xaml looks a little something like this:

<tk:RadListBox Width="150"
    MaxHeight="700"
    VerticalAlignment="Top"
    VerticalContentAlignment="Top"
    tk:DragDropManager.AllowCapturedDrag="True"
    tk:DragDropManager.AllowDrag="True"
    AllowDrop="True"
    Background="Transparent"
    ItemContainerStyle="{StaticResource AttachmentDragItemStyle}"
    ItemTemplateSelector="{StaticResource ThumbnailTemplateSelector}"
    ItemsSource="{Binding Attachments}"
    ScrollViewer.CanContentScroll="False"
    ScrollViewer.HorizontalScrollBarVisibility="Disabled"
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    SelectedItem="{Binding SelectedAttachment, Mode=TwoWay}">
     <tk:RadListBox.ItemsPanel>
           <ItemsPanelTemplate>
                  <VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" />
            </ItemsPanelTemplate>
     </tk:RadListBox.ItemsPanel>
      <tk:RadListBox.DragDropBehavior>
             <behaviors:ListBoxDragDropBehaviorEx />
      </tk:RadListBox.DragDropBehavior>
      <tk:RadListBox.DragVisualProvider>
             <tk:ScreenshotDragVisualProvider />
      </tk:RadListBox.DragVisualProvider>
       <tk:RadListBox.DropVisualProvider>
              <tk:LinearDropVisualProvider />
       </tk:RadListBox.DropVisualProvider>
</tk:RadListBox>

 

with the extended drag drop behavior being:

public class ListBoxDragDropBehaviorEx : ListBoxDragDropBehavior
{
    public override void DragDropCanceled(DragDropState state)
    {
        //base.DragDropCanceled(state);
    }
 
    protected override IEnumerable<object> CopyDraggedItems(DragDropState state)
    {
        //return base.CopyDraggedItems(state);
        return new List<object>();
    }
 
    public override void Drop(DragDropState state)
    {//implement some custom logic here
        //Do not call -> base.Drop(state);
        try
        {
            if (state.IsSameControl)
            {
                if (state.InsertIndex < 0)
                    return;
 
                if (state.DraggedItems != null)
                {
                    foreach (var item in state.DraggedItems)
                    {
                        BaseEntity obj = item as BaseEntity;
                        if (obj == null)
                            continue;
                        var index = state.SourceItemsSource.IndexOf(obj);
                        if (index >= 0)
                        {
                            state.SourceItemsSource.Remove(obj);
                            state.SourceItemsSource.Insert(state.InsertIndex, obj);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            MessageBoxUtil.ShowMessageBox("Drag & Drop error occurred", "Unable to reorder");
        }           
    }
 
    public override void DragDropCompleted(DragDropState state)
    {
        try
        {
            base.DragDropCompleted(state);
        }
        catch (Exception e)
        {
            MessageBoxUtil.ShowMessageBox("Drag & Drop error occurred", "Unable to reorder");
        }
    }
}

 

Now, this works beautifully... when it doesn't crash. But occasionally, if the user decides to perform a crazy mouse seizure and too many drag and drops are issued too quickly, a nullreference exception will be thrown with this stack trace:

 

   at Telerik.Windows.Controls.RadListBoxDragDropHelper.Drop(FrameworkElement dropTarget, FrameworkElement dropItemsControl, Object data, Type itemType)
   at Telerik.Windows.DragDrop.Behaviors.DragDropHelper`2.Drop(Object sender, DragEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at Telerik.Windows.DragDrop.DragDropManager.DelegateHelper.OnDragEventHandler(Object sender, DragEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.OleDropTarget.RaiseDragEvent(RoutedEvent dragEvent, Int32 dragDropKeyStates, Int32& effects, DependencyObject target, Point targetPoint)
   at System.Windows.OleDropTarget.MS.Win32.UnsafeNativeMethods.IOleDropTarget.OleDrop(Object data, Int32 dragDropKeyStates, Int64 point, Int32& effects)
   at MS.Win32.UnsafeNativeMethods.DoDragDrop(IDataObject dataObject, IOleDropSource dropSource, Int32 allowedEffects, Int32[] finalEffect)
   at System.Windows.OleServicesContext.OleDoDragDrop(IDataObject dataObject, IOleDropSource dropSource, Int32 allowedEffects, Int32[] finalEffect)
   at System.Windows.DragDrop.OleDoDragDrop(DependencyObject dragSource, DataObject dataObject, DragDropEffects allowedEffects)
   at System.Windows.DragDrop.DoDragDrop(DependencyObject dragSource, Object data, DragDropEffects allowedEffects)
   at Telerik.Windows.DragDrop.DragDropManager.DoDragDrop(DependencyObject dragSource, Object data, DragDropEffects allowedEffects, DragDropKeyStates initialKeyState, Object dragVisual, Point relativeStartPoint, Point dragVisualOffset)
   at Telerik.Windows.DragDrop.DragInitializer.StartDrag()
   at Telerik.Windows.DragDrop.DragInitializer.StartDragPrivate(UIElement sender)
   at Telerik.Windows.DragDrop.DragInitializer.DragSourceOnMouseMove(Object sender, MouseEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.MouseDevice.Synchronize()
   at System.Windows.Input.MouseDevice.ChangeMouseCapture(IInputElement mouseCapture, IMouseInputProvider providerCapture, CaptureMode captureMode, Int32 timestamp)
   at System.Windows.Input.MouseDevice.Capture(IInputElement element, CaptureMode captureMode)
   at Telerik.Windows.DragDrop.DragInitializer.DragSourceMouseLeave(Object sender, MouseEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList`1 otherOrigins, DeferredElementTreeState& oldTreeState, Action`2 originChangedAction)
   at System.Windows.Input.MouseDevice.ChangeMouseOver(IInputElement mouseOver, Int32 timestamp)
   at System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.ShowDialog()

^ This is the point where the window opens, so obviously there is no code between here and the crash that I have control of. I am wondering why this happens sometimes and what can be done to fix this? I see no way to prevent this crash as it all seems to be happening inside telerik code. Please advise. 

3 Answers, 1 is accepted

Sort by
0
Dilyan Traykov
Telerik team
answered on 23 Mar 2018, 11:37 AM
Hello Andrey,

I tried to reproduce the aforementioned exception at my end using the code you provided, but was, unfortunately, unable to do so. I've attached the project I used in the process to my reply for your reference. Could you please have a look at it and let me know what modifications I can make to it in order to replicate the issue?

Thank you in advance for your cooperation on the matter.

Regards,
Dilyan Traykov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Andrey
Top achievements
Rank 1
answered on 23 Mar 2018, 08:22 PM

Ugh... you guys aren't gonna believe this. So I just "fixed" it myself, and it is the most mind-bogglingly, heart-breakingly, earth-shatteringly stupid coding "solution" I've ever seen. Are you ready to hear this? ...I mean, really ready? Are you sure? ...No, I don't think you are.... you might want to sit down for this one first.

 

So, I made a test project to reproduce this easier myself, and I also couldn't. This prompted me to take a deeper look at my own xaml... Turns out the problem line was this in the list box:

ItemTemplateSelector="{StaticResource ThumbnailTemplateSelector}"

 

Removing this one line makes the whole thing work. (And by "work" I mean "not crash", since it makes the list box items appear as just text of their .ToString()s, which of course isn't the desired result). But once I figured this out, I went inside, followed the trail of styles and templates, until eventually, I came to this inside the deepest ControlTemplate:

<TextBlock Margin="0,-5,0,0"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    Panel.ZIndex="1000"
    FontWeight="SemiBold"
    Padding="2">
    <TextBlock.Inlines>
        <Run Text="{Binding Size, Mode=OneWay}" />
    </TextBlock.Inlines>
</TextBlock>

 

My process of elimination eventually led to me removing this one textblock, which... magically fixed it. But of course this isn't quite ideal either, since I need this text to show up in my ListBoxItems. So what was my final solution? I "refactored" it into this:

<TextBlock Margin="0,-5,0,0"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    Panel.ZIndex="1000"
    FontWeight="SemiBold"
    Text="{Binding Size}"
    Padding="2"/>     
0
Andrey
Top achievements
Rank 1
answered on 23 Mar 2018, 08:33 PM

I'm still sitting here in stunned disbelief at how something like this even happens. How can simple TextBlock string binding semantics manage to break your entire drag and drop functions is beyond me... I'm leaving this whole experience with my faith in WPF badly shaken (and pretty much, Microsoft in general!)

 

...Needless to say, I'm not satisfied with this revelation at all, but I guess this will just have to be one of the great mysteries of our time. I'm just glad I was here to share it with someone.

 

Cheers,

- Andrey, a random WPF developer from Texas

Efi
Top achievements
Rank 1
commented on 27 Jan 2022, 10:01 AM

Thanks, I also faced a similar issue, while sometimes Telerik DragDrop crashed, and only stopping using Inlines made it works.
Tags
DragAndDrop
Asked by
Andrey
Top achievements
Rank 1
Answers by
Dilyan Traykov
Telerik team
Andrey
Top achievements
Rank 1
Share this question
or