Description
Description
When UseLayoutRounding=true
, the DataGrid
can hang in an endless loop trying to get a cell into view after resetting the data then setting DataGrid.CurrentCell
.
It appears to happen particularly when the column expands beyond the width of the DataGrid, and only on certain screen scales.
Reproduction Steps
- Set screen scale to 125% in System > Display Settings
- Open and run this project: TestWpfColumnFreeze.zip
- Double click on one of the cells that says "Double click on me"
Expected behavior
Should not hang at any screen scale or layout rounding setting
Actual behavior
The application hangs and does not respond to input.
The offending method appears to be in DataGridCellsPanel.BringIndexIntoView
, where it gets stuck in this loop:
while (!IsChildInView(index, out newHorizontalOffset) && !DoubleUtil.AreClose(value, newHorizontalOffset))
{
retryRequested = true;
scrollInfo.SetHorizontalOffset(newHorizontalOffset);
UpdateLayout();
value = newHorizontalOffset;
}
Stack Trace:
System.Private.CoreLib.dll!System.Threading.Monitor.Enter(object obj, ref bool lockTaken) Unknown
PresentationCore.dll!System.Windows.Media.Visual.GetDpi() Unknown
PresentationCore.dll!System.Windows.UIElement.Arrange(System.Windows.Rect finalRect) Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.DataGridColumnHeadersPresenter.ArrangeOverride(System.Windows.Size finalSize) Line 168 C#
PresentationFramework.dll!System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect finalRect) Line 3718 C#
PresentationCore.dll!System.Windows.UIElement.Arrange(System.Windows.Rect finalRect) Unknown
PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() Unknown
> PresentationFramework.dll!System.Windows.Controls.DataGridCellsPanel.BringIndexIntoView(int index) Line 1580 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Private.CoreLib.dll!System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(object obj, System.Span<object> copyOfArgs, System.Reflection.BindingFlags invokeAttr) Unknown
System.Private.CoreLib.dll!System.Reflection.MethodBaseInvoker.InvokeWithOneArg(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) Unknown
System.Private.CoreLib.dll!System.Delegate.DynamicInvokeImpl(object[] args) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Line 83 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Line 24 C#
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Line 424 C#
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj) Line 99 C#
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 85 C#
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Line 350 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Line 1250 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled) Line 1367 C#
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled) Line 192 C#
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Line 223 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Line 73 C#
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Line 24 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Line 990 C#
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(nint hwnd, int msg, nint wParam, nint lParam) Line 180 C#
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Line 1281 C#
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) C#
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) C#
TestWpfColumnFreeze.dll!TestWpfColumnFreeze.App.Main() Unknown
Regression?
Also happens with latest .NET Framework, not sure about earlier versions.
Known Workarounds
Turning off layout rounding for the DataGridRow appears to avoid the issue.
Impact
No response
Configuration
Running on Windows 11 23H2, .NET runtime 8.0.8 or 7.0.0
Reproducible on both x64 and ARM64 architectures.
Other information
No response