NullReferenceException on WM_THEMECHANGED if a standard control with OverridesDefaultStyle set to True
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Description
We, at DevExpress, received a significant number of customer reports related to a NullReferenceException thrown on the WM_THEMECHANGED system message. The issue occurs when this system message is received in an application with a standard control whose OverridesDefaultStyle property is set to True. Some customers do not set this property explicitly but use other popular third-party controls that require this property to be set to True. We managed to reproduce it with our controls, but the issue looks general and theoretically can occur without DevExpress classes.
Our research shows that the issue occurs due to a missing null check in the OnBindingValueInThemeStyleChanged method of the StyleHelper class:
https://github.com/dotnet/wpf/blob/37b9597bebaf48196a05f6d6212ec1e9bc24352f/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/StyleHelper.cs#L5212
To simulate the WM_THEMECHANGED system message, you can call the InvalidateCache method of the SystemParameters class:
```cs
var invalidateCacheMethod = typeof(SystemParameters).GetMethod("InvalidateCache",
BindingFlags.NonPublic | BindingFlags.Static, Type.EmptyTypes)!;
invalidateCacheMethod.Invoke(null, null);
```
IMPORTANT: The issue occurs ONLY in .NET. The same error does not occur in .NET Framework.
### Reproduction Steps
1. Run the attached project ([dxSample.zip](https://github.com/user-attachments/files/24076548/dxSample.zip)).
2. Click the Test button.
The attached screencast illustrates these steps and the problematic behavior:
https://github.com/user-attachments/assets/2decd8fe-e6db-4f21-9b21-24884b1ef131
### Expected behavior
No NullReferenceException is thrown.
### Actual behavior
NullReferenceException is thrown.
### Regression?
Yes. The issue occurs only in .NET. In .NET Framework, the same steps do not cause a NullReferenceException.
### Known Workarounds
_No response_
### Impact
Potentially, this can affect a significant number of DevExpress customers.
### Configuration
_No response_
### Other information
```callstack
System.NullReferenceException: 'Object reference not set to an instance of an object.'
PresentationFramework.dll!System.Windows.StyleHelper.OnBindingValueInThemeStyleChanged(object sender, MS.Internal.Data.BindingValueChangedEventArgs e) Line 2378 C#
PresentationFramework.dll!System.Windows.Data.BindingExpression.TransferValue(object newValue, bool isASubPropertyChange) Line 1069 C#
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(int k, System.ComponentModel.ICollectionView collectionView, object newValue, bool isASubPropertyChange) Line 583 C#
PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(object o, string propName) Line 278 C#
WindowsBase.dll!System.Windows.WeakEventManager.ListenerList.DeliverEvent(object sender, System.EventArgs e, System.Type managerType) Unknown
WindowsBase.dll!System.Windows.WeakEventManager.DeliverEventToList(object sender, System.EventArgs args, System.Windows.WeakEventManager.ListenerList list) Unknown
PresentationFramework.dll!MS.Internal.Data.StaticPropertyChangedEventManager.OnStaticPropertyChanged(MS.Internal.Data.StaticPropertyChangedEventManager.TypeRecord typeRecord, System.ComponentModel.PropertyChangedEventArgs args) Line 444 C#
PresentationFramework.dll!System.Windows.SystemParameters.OnPropertiesChanged(string[] propertyNames) Line 4853 C#
PresentationFramework.dll!System.Windows.SystemParameters.InvalidateProperty(int slot, string name) Line 4864 C#
PresentationFramework.dll!System.Windows.SystemParameters.InvalidateCache() Line 4886 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Private.CoreLib.dll!System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(object obj, System.Reflection.BindingFlags invokeAttr) Line 57 C#
ThemeCrash.dll!ThemeCrash.MainWindow.Button_Click(object sender, System.Windows.RoutedEventArgs e) Line 17 C#
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnClick() Line 223 C#
PresentationFramework.dll!System.Windows.Controls.Button.OnClick() Line 184 C#
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) Line 413 C#
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent) Unknown
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(nint hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(nint hwnd, MS.Internal.Interop.WindowMessage msg, nint wParam, nint lParam, ref bool handled) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(nint hwnd, int msg, nint wParam, nint lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Line 1539 C#
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Line 1214 C#
ThemeCrash.dll!ThemeCrash.App.Main() Unknown
```
Contributor guide
Assessment
This issue has not been assessed yet.