2

In my WPF app, I have WPF windows that can open other WPF dialog windows, which I do as follows:

PickForEveryone PickForEveryoneWindow = new PickForEveryone(sSelRecipe, selMRM.sDay, selMRM.MealTypeID);
PickForEveryoneWindow.Owner = this;
PickForEveryoneWindow.ShowDialog();

Where PickForEveryone is defined as:

public partial class PickForEveryone : Window

and

<Window x:Class="PFWb0.PickForEveryone"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
 ShowInTaskbar="False"
 Title="Pick Recipe For All" Height="536" Width="441" 
 WindowStartupLocation="CenterOwner">

And contains a Grid with a DataGrid and a few buttons and check boxes.

Which works fine on my development computers. However, my client keeps seeing the dialog windows leave part of their display as visual litter on top of the parent window when the dialog window closes. That is, only some of the window undraws when ShowDialog() returns.

I tried adding this.InvalidateVisual(); below the above code, but it didn't solve the problem.

I also saw a suggestion here (for another kind of WPF display problem) to call OnRender() to force a redraw, but OnRender requires a parameter of type DrawingContext, which I don't know how to get.

So, I am asking if anyone knows how to either fix the display problem in the first place, or how to recover from it by getting WPF to redraw a window.

Update: As seen in comments to suggested answers below, I still have no solution that works on my client's computers, and my workaround (of having the windows dodge each other) is no longer enough. The only thing that works is to minimize and maximize the polluted underlying window.

Dronz
  • 1,970
  • 4
  • 27
  • 50
  • Graphic "bugs" on a specific computer is very likely a result of a bad display driver on that computer. If the problem is in DirectX then WPF can trigger the problem while say a Windows Forms application will not. – Martin Liversage Feb 09 '11 at 08:38
  • Yeah. I found related complaints on the MSDN forum some years ago, but no one had a fix. Also my client is running the latest drivers for his video adapter (which doesn't mean it doesn't have a bug, of course, but it means there's no easy fix available by updating drivers). Also, he actually tried inserting a different video card, and it still showed that problem on his machine. I am thinking it may be Vista at this point, or more accurately, what you say - some particular drivers. – Dronz Feb 10 '11 at 01:22

5 Answers5

5

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 :

shascoet
  • 51
  • 1
  • 4
1

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;
        }
    }
MTR
  • 1,690
  • 3
  • 20
  • 47
  • Ok, my workaround of moving the windows so they don't overlap, has been outgrown by my application, which now sometimes needs more screen space so overlap isn't so easily avoidable. So, I am going to try this out on the client's computer tomorrow. Thanks for the suggestion MTR. I'm curious if this will work and I'll post back here after I know. – Dronz Apr 24 '12 at 05:37
0

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!

Dronz
  • 1,970
  • 4
  • 27
  • 50
  • Oh oops, apparently this does not entirely solve the problem. If anyone knows anything to contribute to this question, please let me know. – Dronz Jan 19 '11 at 20:54
  • I tried UpdateLayout(), which had no effect. I have now also tried making the dialog window minimize before closing it. That didn't work either. – Dronz Feb 03 '11 at 16:30
  • Then I added code to move the dialog window to off-screen coordinates, then minimize it, then close it, and that also did not work. It does change the "going away" animation on my development computer, so that it blinks away instead of shrinking and then going away, but it still leaves garbage on the parent window. – Dronz Feb 03 '11 at 16:30
  • However, my client reports that if he manually moves the dialog window, it determines where the garbage gets left, so I think that moving the window will work, if I can get it to really do so before it closes. I imagine that by making calls to change the X and Y and minimize and then close, the position and minimize calls are not having effect before the close takes effect. How would anyone recommend that I effect a delay or force visual update on the dialog window before closing it? – Dronz Feb 03 '11 at 16:31
0

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;
AH.
  • 2,913
  • 1
  • 28
  • 26
  • Actually, none of the solutions I have tried actually work on the client's computer. – Dronz Feb 10 '11 at 01:23
  • Thanks AH. I posted that one in my first "answer" to myself above. That one should work (in the clumsy way that it works), but I haven't actually had my client run it. If the scheme I mentioned yesterday doesn't work, I'll have him give that one a shot. – Dronz Feb 10 '11 at 17:17
0

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...

Dronz
  • 1,970
  • 4
  • 27
  • 50
  • And THAT attempt ALSO failed. In the end, I have just avoided stacking those windows, although other windows seem to be able to stack without leaving garbage, which I have no idea why these would be a problem and not the others, but since the cause seems to be a driver bug or something, I guess I shouldn't expect too much logic. The workaround of making the windows not overlap is actually a nice design shift anyway, so I'm giving up for now on this issue, but am still curious if anyone has anything! – Dronz Mar 03 '11 at 06:08