Fix display garbage left by WPF dialog window?

不打扰是莪最后的温柔 提交于 2019-12-04 18:05:47

I had a similar problem on a specific computer with an ATOM N270 processor. The problem seamed to be linked to the graphic hardware acceleration.

To deactivate the accelaration, just add this to the registery (this will deactivate hardware acceleration for all WPF applications) :

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics\DisableHWAcceleration

I had to create the Avalon.Graphics folder.

DisableHWAcceleration is a DWORD that has to be set to 1.

This had solve my problem, if I reactivate the acceleration, the problem come back.

Hope this helps.

References :

This ugly code works for me:

        void RefreshWindow()
    {
        switch (WindowState)
        {
            case WindowState.Maximized:
                {
                    double oldWidth = Width;
                    Width = System.Windows.SystemParameters.PrimaryScreenWidth - 1;
                    WindowState = System.Windows.WindowState.Normal;
                    WindowState = System.Windows.WindowState.Maximized;
                    Width = oldWidth;
                }
                break;
            case WindowState.Normal:
                if (Width > 1)
                {
                    Width -= 1;
                    Width += 1;
                }
                else
                {
                    Width += 1;
                    Width -= 1;
                }
                break;
            case WindowState.Minimized:
            default:
                // no action necessary
                break;
        }
    }

So I have been looking for an answer to this on the MS forums, and apparently, variations of this question have been a asked for a few years now.

Sometimes, they say, the problem has to do with video drivers, of all things, although in my case, my client has recently updated his video drivers.

My impression is that Microsoft thought they designed WPF so that a developer should never need to do such a thing as force a redraw of the display, so they make no way to do so by design. Of course, when things go wrong for whatever reason, this means there is no straightforward way to do so. And the ways that seem like they might do so (such as InvalidateVisual()), don't.

But I did find one hack that does work. Well, two. The ugly one is to tell the window to minimize and return to normal. But that results in a visual animation of it doing so, which is not ideal. In my case, it also made it hide behind other open windows, requiring me to make it go topmost. But is does solve the problem, in a jarring way.

Code after ShowDialog:

    this.WindowState = WindowState.Minimized;
    this.WindowState = WindowState.Normal;
    this.Topmost = true;

The better hack, looks a bit like this:

Code outside:

public delegate void NoArgDelegate();

Code after ShowDialog:

    this.Dispatcher.Invoke(
    System.Windows.Threading.DispatcherPriority.Loaded,
        (NoArgDelegate)delegate {}
    );

Presto ala kazzam!

This solution works, but it is not very pretty (easy to see that dialog is minimized and then set to normal).

this.WindowState = WindowState.Minimized;
this.WindowState = WindowState.Normal;
this.Topmost = true;

So far nothing I have tried actually works on my client's computer. I have a new fix (workaround hack) attempt in for client testing, which involves moving the window away, and trying to make it actually take effect by launching an empty window just before I close the dialog window. Sigh...

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!