wpf: Crash due to exception "Height must be non-negative."

  • .NET Core Version: 4.8 and 4.8.1
  • Windows version: 22H2
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
  • Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc…)? No.

Problem description: Crash related to updating an ObservableCollection in WPF. Started occurring after recent application of update KB5017271. The issue was not occurring before this. Crashing has also been observed on Windows 10 machines, after the application of KB5017497. Our application has not been updated. Crash appears to be related to these .NET updates.

Actual behavior: Call stacks are all identical:

   at System.Windows.Size.set_Height(Double value)\r\n   
   at System.Windows.Controls.VirtualizingStackPanel.AdjustEffectiveOffsetForItemsChange(ItemsChangedEventArgs args)\r\n   
   at System.Windows.Controls.VirtualizingStackPanel.ShouldItemsChangeAffectLayoutCore(Boolean areItemChangesLocal, ItemsChangedEventArgs args)\r\n   
   at System.Windows.Controls.VirtualizingPanel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)\r\n   
   at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)\r\n   
   at System.Windows.Controls.ItemContainerGenerator.OnItemRemoved(Object item, Int32 itemIndex, NotifyCollectionChangedEventArgs collectionChangedArgs)\r\n   
   at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)\r\n   
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)\r\n   
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)\r\n   
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)\r\n   
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)\r\n   
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)\r\n   
   at System.Windows.Controls.ItemCollection.OnViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)\r\n  
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)\r\n   
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)\r\n   
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)\r\n   
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)\r\n   
   at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)\r\n   
   at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)\r\n   
   at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)\r\n   
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.RemoveItem(Int32 index)\r\n   
   

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

@billhenn - The issue has been fixed on .NET Framework and will be available in upcoming servicing updates.

@dipeshmsft I can confirm the issue is no longer reproducible in our Sample Browser application on Win10 22H2 after applying the January .NET Framework update. Thank you for helping get this issue resolved!

@Pierre-Alianza, @MorfMichael, @boydpatterson, we have tried to fix this issue in the latest windows release, can you please remove the opt-out switch and check if the applications are working as they used to work before ?

A user of our controls who has been bitten by this .NET Framework bug let us know about a workaround that Microsoft shared with him on the issue, so I wanted to repost it here for others. The response was to use an AppContext switch as demonstrated in the following snippet:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Windows.Controls.VirtualizingStackPanel.OptOutOfCollectionChangeFix=true"/>
  </runtime>
</configuration>

I hope this can help some others until the fix is released.

Cool, thank you @boydpatterson, I confirm this reproduces the issue for me.

This issue was brought to our attention by one of our customers who began seeing the same stack trace on test machines after receiving the already mentioned update. We have been able to consistently reproduce this issue in a sample application we provide for evaluating our controls. The issue was reproduced with .NET Framework 4.8, but the same steps did not reproduce the issue with .NET 5. Turning off virtualization (VirtualizingPanel.IsContainerVirtualizable="False") also prevents the exception from being raised.

Since it is unclear whether or not this issue has been reproduced internally, we wanted to offer up our sample application and the following steps to help reproduce and resolve this issue.

Acquire the Actipro WPF Controls Sample Browser from our public repo: https://github.com/Actipro/WPF-Controls

  1. Open the Sample Browser using /Samples/SampleBrowser/SampleBrowser.sln
  2. This application supports multiple targets, so run the application in the debugger using .NET Framework.
  3. If evaluation license dialog is displayed, click Continue.
  4. Under “Discover our WPF Controls”, click the “Grids” product to open the overview page of samples for that product.
  5. Under the “TreeListBox QuickStarts” section (see headers on left), click the “Filtering” link to open that sample.
  6. This sample features a “TreeListBox” control on the left with controls for sample options on the top-right.
  7. In the “TreeListBox” control under “North America”, expand the “Canada” node.
  8. (Very Important) Scroll down slowly (line by line using scroll down button of scrollbar) until “United States of America” is the last visible node.
  9. Expand “United States of America”.
  10. (Very Important) Scroll down one time so “Alabama” is the last visible node.
  11. In the “Sample Options” control box on the top-right, set the “Value” option to “arg”.
  12. Check the “Is filter active” box.

At this point, the following stack trace was reported on Windows 11 using .NET Framework 4.8:

System.ArgumentException
  HResult=0x80070057
  Message=Height must be non-negative.
  Source=WindowsBase
  StackTrace:
   at System.Windows.Size.set_Height(Double value)
   at System.Windows.Controls.VirtualizingStackPanel.AdjustEffectiveOffsetForItemsChange(ItemsChangedEventArgs args)
   at System.Windows.Controls.VirtualizingStackPanel.ShouldItemsChangeAffectLayoutCore(Boolean areItemChangesLocal, ItemsChangedEventArgs args)
   at System.Windows.Controls.VirtualizingPanel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
   at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)
   at System.Windows.Controls.ItemContainerGenerator.OnItemRemoved(Object item, Int32 itemIndex, NotifyCollectionChangedEventArgs collectionChangedArgs)
   at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at ActiproSoftware.Windows.Controls.Grids.Primitives.TreeNodeItemCollection.RaiseCollectionChangedEvent(NotifyCollectionChangedEventArgs e) in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\Primitives\TreeNodeItemCollection.Wpf.cs:line 105
   at ActiproSoftware.Windows.Controls.Grids.Primitives.TreeNodeItemCollection.RemoveRangeInternal(Int32 index, Int32 count) in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\Primitives\TreeNodeItemCollection.cs:line 314
   at ActiproSoftware.Windows.Controls.Grids.TreeListBox.<>c__DisplayClass82_1.<UpdateAllTreeNodeVisibility>b__0(Int32 currentIndex) in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\TreeListBox.cs:line 1576
   at ActiproSoftware.Windows.Controls.Grids.TreeListBox.UpdateAllTreeNodeVisibility() in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\TreeListBox.cs:line 1629
   at ActiproSoftware.Windows.Controls.Grids.TreeListBox.ApplyFilter() in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\TreeListBox.cs:line 289
   at ActiproSoftware.Windows.Controls.Grids.TreeListBox.<>c__DisplayClass72_0.<RequestApplyFilter>b__0() in C:\Code\Actipro\WPF-Controls-Source\Source\Grids\UI\Controls.Grids\TreeListBox.cs:line 1335
   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.DispatcherOperation.InvokeImpl()
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(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.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at ActiproSoftware.SampleBrowser.App.Main()

Thanks, @boydpatterson @MorfMichael for the confirmation. I will go ahead and close the issue.

For Windows 11 uninstalling KB5017271 resolves the crash. For more information: the ObservableCollection is used as the ItemsSource for a ListView.

Do you have a repro project?

Looks similar to #2854.