dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.08k stars 1.17k forks source link

After Modified screen dpi,Unloaded/Loaded is trigged unexpectedly #2255

Open Kybs0 opened 4 years ago

Kybs0 commented 4 years ago

When I modify the system dpi in screen setting, a userControl in window raises unload event, as more amazing unload event of window that contains the userControl is not triggered.

As all I known, loaded/unloaded can be triggered by these cases: FrameworkElement raises loaded/unloaded when it's added/removed to visual tree. TabControl selection change from tab A to tab B, raise A'UnLoaded and B'Loaded Expander、MenuItem and so on...All these cases, emmm.. seems like loaded/unloaded event raises just as element or it's parent leave from or add to wpf visual tree.

But, How Unloaded/Loaded can be raised by changing screen dpi ? For testing, I create a window, then create and add a simple UserControl named A in window xaml, continue to create and add UserControl named B in A xaml. After window is showed in screen, modify screen dpi from 100% to 150%, UserControl A raise unloaded event, then UserControl B raise unloaded. As joking, window itself has no unloaded. unloaded event stack: image As additional, before modify dpi setting, drag window and move near the taskbar, the issue occurs more probabily~ image

More details please see my blog https://www.cnblogs.com/kybs0/p/11943313.html Expecting you advise for this bug~

trovialdo commented 4 years ago

Using .NET Framework 4.8 sometimes the constructor of the control is also called again (so local state in the control is lost due to a new instance being used). This happens once in a while when changing scaling on a 4K monitor, e.g. 100% -> 200% -> 125% -> 200% -> 150%, ... the order does not matter.

Therefore workarounds of unsubscribing from the Loaded event or using a guard: bool _hasBeenLoaded are not sufficient.

Windows 10 Version 10.0.18363 Build 18363

Stack trace:

        Constructor of the control currently visible.
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref System.Threading.StackCrawlMark stackMark) Line 5476    C#
    mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) Line 193 C#
    mscorlib.dll!System.RuntimeType.CreateInstanceImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes, ref System.Threading.StackCrawlMark stackMark) Line 5321    C#
    mscorlib.dll!System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) Line 107    C#
    mscorlib.dll!System.Activator.CreateInstance(System.Type type, object[] args) Line 112  C#
    System.Xaml.dll!System.Xaml.Schema.SafeReflectionInvoker.CreateInstanceCritical(System.Type type, object[] arguments)   Unknown
    System.Xaml.dll!System.Xaml.Schema.SafeReflectionInvoker.CreateInstance(System.Type type, object[] arguments)   Unknown
    System.Xaml.dll!System.Xaml.Schema.XamlTypeInvoker.CreateInstance(object[] arguments)   Unknown
    System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(System.Xaml.XamlType xamlType, object[] args)  Unknown
    System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args)  Unknown
    System.Xaml.dll!MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args)   Unknown
    System.Xaml.dll!System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(MS.Internal.Xaml.Context.ObjectWriterContext ctx)   Unknown
    System.Xaml.dll!System.Xaml.XamlObjectWriter.WriteEndObject()   Unknown
    System.Xaml.dll!System.Xaml.XamlWriter.WriteNode(System.Xaml.XamlReader reader) Unknown
    PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader templateReader, System.Xaml.XamlObjectWriter currentWriter)  Unknown
    PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlObjectWriter objectWriter)  Unknown
    PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(System.Windows.DependencyObject container, System.Windows.Markup.IComponentConnector componentConnector, System.Windows.Markup.IStyleConnector styleConnector, System.Collections.Generic.List<System.Windows.DependencyObject> affectedChildren, System.Windows.UncommonField<System.Collections.Hashtable> templatedNonFeChildrenField)   Unknown
    PresentationFramework.dll!System.Windows.FrameworkTemplate.LoadContent(System.Windows.DependencyObject container, System.Collections.Generic.List<System.Windows.DependencyObject> affectedChildren)    Unknown
    PresentationFramework.dll!System.Windows.StyleHelper.ApplyTemplateContent(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> dataField, System.Windows.DependencyObject container, System.Windows.FrameworkElementFactory templateRoot, int lastChildIndex, System.Collections.Specialized.HybridDictionary childIndexFromChildID, System.Windows.FrameworkTemplate frameworkTemplate) Unknown
    PresentationFramework.dll!System.Windows.FrameworkTemplate.ApplyTemplateContent(System.Windows.UncommonField<System.Collections.Specialized.HybridDictionary[]> templateDataField, System.Windows.FrameworkElement container)   Unknown
    PresentationFramework.dll!System.Windows.FrameworkElement.ApplyTemplate()   Unknown
    PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize)    Unknown
    PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize)    Unknown
    PresentationFramework.dll!System.Windows.Controls.Control.MeasureOverride(System.Windows.Size constraint)   Unknown
    PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize)    Unknown
    PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize)    Unknown
    PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() Unknown
    PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg)   Unknown
    PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()  Unknown
    PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()    Unknown
    PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget)    Unknown
    PresentationCore.dll!System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(object resizedCompositionTarget)    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.DispatcherOperation.InvokeImpl()   Unknown
    WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state)  Unknown
    WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980  C#
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928  C#
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 917    C#
    WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state)  Unknown
    WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()   Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()  Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)  Unknown
    WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
    WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) 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(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam)  Unknown
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame)   Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame)   Unknown
    PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)   Unknown
    PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)  Unknown
    PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window)  Unknown
    PresentationFramework.dll!System.Windows.Application.Run()  Unknown

This might be a different issue but it has the same trigger and is also related to DPI.