Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SizeToContent is overwritten from WidthAndHeight to Manual by Avalonia on DPI Change #4739

Closed
jtbrower opened this issue Sep 25, 2020 · 1 comment · Fixed by #6254
Closed

Comments

@jtbrower
Copy link

Summary

If you create a Window with SizeToContent set to WidthAndHeight, execute the program on Windows and then cause a DPI Change to occur, Avalonia will overwrite the SizeToContent by setting it to Manual.

Reproduction

I created a sample solution to demonstrate the problem. It is a Window that shows a list. The Window provides a button that when you click to add additional items to the list. You will see that the Window resizes to Content as expected.

Now, force a ScaleChange (DPI Change) to occur by either dragging the Window to another one of your PC's monitors that has a different DPI, or using the Windows 10 settings, change the scaling factor of the monitor the application is currently being displayed on to something other then the current value.

As soon as the DPI/ScaleChange occurs, Avalonia will change SizeToContent from WidthAndHeight to Manual. This then fires a debug printout that I added when that property changes that will show a stack trace that led to the property change. You can see an example of that stack trace below.

Versions

I tried this from the latest Avalonia production version all the way up to the current 0.10.0-preview5 version and the issue exists in both.

Stack Trace (Not an Exception, just for your Help)

From first glance at this stack trace it would seem that the DPI change causes a Window Resize and then Avalonia treats that resize as if the user manually resized a Window that had SizeToContent set, but their manual resize event would remove that. However, in this case I am not manually resizing the Window, it is a side effect of the DPI Change / ScaleChanged.

Someone changed my SizeToContentProperty from WidthAndHeight to Manual
   at System.Environment.get_StackTrace()
   at SizeToContentChanged.MainWindow.<>c.<.ctor>b__6_0(AvaloniaPropertyChangedEventArgs a) in D:\git\SizeToContentChanged\SizeToContentChanged\MainWindow.axaml.cs:line 24
   at System.Reactive.AnonymousObserver`1.OnNextCore(T value) in /_/Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:line 67
   at System.Reactive.ObserverBase`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs:line 36
   at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 148
   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change)
   at Avalonia.AvaloniaObject.Avalonia.PropertyStore.IValueSink.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change)
   at Avalonia.ValueStore.SetExisting[T](Object slot, StyledPropertyBase`1 property, T value, BindingPriority priority)
   at Avalonia.ValueStore.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority)
   at Avalonia.AvaloniaObject.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority)
   at Avalonia.Controls.Window.set_SizeToContent(SizeToContent value)
   at Avalonia.Controls.Window.HandleResized(Size clientSize)
   at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.Interop.UnmanagedMethods.DefWindowProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.Interop.UnmanagedMethods.DefWindowProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.Interop.UnmanagedMethods.SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, Int32 x, Int32 y, Int32 cx, Int32 cy, SetWindowPosFlags uFlags)
   at Avalonia.Win32.Interop.UnmanagedMethods.SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, Int32 x, Int32 y, Int32 cx, Int32 cy, SetWindowPosFlags uFlags)
   at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
   at Avalonia.Win32.Interop.UnmanagedMethods.GetMessage(MSG& lpMsg, IntPtr hWnd, UInt32 wMsgFilterMin, UInt32 wMsgFilterMax)
   at Avalonia.Win32.Interop.UnmanagedMethods.GetMessage(MSG& lpMsg, IntPtr hWnd, UInt32 wMsgFilterMin, UInt32 wMsgFilterMax)
   at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken cancellationToken)
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode)
   at SizeToContentChanged.Program.Main(String[] args) in D:\git\SizeToContentChanged\SizeToContentChanged\Program.cs:line 12

Example Program

SizeToContentChanged.zip

Workaround

I simply listen for the property to change and then I will set it back to the proper value using the following code.


//Note that when a DPI changes Avalonia wrongfully overwrites the SizeToContent with Manual.  This
// workaround will fix that.
var sizeToContentWorkaroundSubscription =
       SizeToContentProperty.Changed.Subscribe(a => { if (SizeToContent != SizeToContent.WidthAndHeight) SizeToContent = SizeToContent.WidthAndHeight; });

@grokys
Copy link
Member

grokys commented Jul 14, 2021

This also happens when minimizing and restoring a window on win32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants