Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix the WPF form resize - controls lagging behind and black background?

Tags:

wpf

I have a very simple WPF window - the only thing in it is a right-aligned button. When I resize the window by dragging the left boundary, the button jumps around - a lot. Try it yourself, drag the left boundary back and forth.

Additionally, a black background becomes exposed temporarily during resizes.

In this question, I asked a similar question about Windows Forms. The only answer I got suggested that this is fixed in WPF, however, amazingly, not only is it not fixed, but WPF also adds a second visual bug - the temporary black background.

Here's what the control lag looks like; this occurs when I resize the window by its top border (recorded with a camera because screen-cap made it less obvious by making everything slow):

                                                  enter image description here

Example of the black border: this was captured while resizing the window; it's only like this for a split second but it's very noticeable:

                                      enter image description here

Am I doing something wrong? How can I have my controls stay visually in one place during resizes? How can I avoid the black border?

Note: the button ends up in the correct place eventually - it only jumps around briefly during the resize.

like image 477
Roman Starkov Avatar asked Sep 05 '09 09:09

Roman Starkov


Video Answer


4 Answers

This is complete working code based on Wieser Software Ltd's 2nd solution.

public partial class MainView : Window {     public MainView()     {         InitializeComponent();          //ensure win32 handle is created         var handle = new WindowInteropHelper(this).EnsureHandle();          //set window background         var result = SetClassLong(handle, GCL_HBRBACKGROUND, GetSysColorBrush(COLOR_WINDOW));     }      public static IntPtr SetClassLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)     {         //check for x64         if (IntPtr.Size > 4)             return SetClassLongPtr64(hWnd, nIndex, dwNewLong);         else             return new IntPtr(SetClassLongPtr32(hWnd, nIndex, unchecked((uint)dwNewLong.ToInt32())));     }      private const int GCL_HBRBACKGROUND = -10;     private const int COLOR_WINDOW = 5;      [DllImport("user32.dll", EntryPoint = "SetClassLong")]     public static extern uint SetClassLongPtr32(IntPtr hWnd, int nIndex, uint dwNewLong);      [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")]     public static extern IntPtr SetClassLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);      [DllImport("user32.dll")]     static extern IntPtr GetSysColorBrush(int nIndex); } 
like image 164
ghord Avatar answered Sep 20 '22 14:09

ghord


This doesn't seem to be possible in the current versions of WPF.

like image 44
Roman Starkov Avatar answered Sep 19 '22 14:09

Roman Starkov


There are two solutions, described here: http://wieser-software.blogspot.co.uk/2012/06/wpf-window-rendering-woes.html

  1. Hook WndProc and handle WM_ERASEBKGND and draw the system WINDOW_COLOR on the background, or another color to suit your application theme.
  2. Call SetClassLong to set the Window Class Background Brush

    SetClassLong(Handle, GCL_HBRBACKGROUND, GetSysColorBrush(COLOR_WINDOW));

like image 21
Anthony Wieser Avatar answered Sep 19 '22 14:09

Anthony Wieser


I believe that the temporary black background is a WPF issue related to the fact that WPF uses DirectX as rendering mechanism, and when you resize the windows it has to synchronize drawing with the windowing system. This may also explain why the button is misplaced in relation to the window while dragging the window border. Drawing the non-client area of the window is much slower than drawing what's inside the window, and if you move the mouse fast on a slow computer the discrepancies between the border end the internals of the window will probably be more noticeable.

Supposedly this only happens on Vista with Aero enabled, and it should have been fixed in Vista SP1. However, I just tested on SP2, and I did still see a little bit of black background, but only when Aero was enabled. My graphics card is pretty fast so it was hardly noticeable.

If my analysis is correct the only way you can fix your problem is to getter a faster graphics card or turn off Aero.

like image 35
Martin Liversage Avatar answered Sep 19 '22 14:09

Martin Liversage