views:

285

answers:

3

I have discovered a strange bug with my WPF application and I am trying to determine whether it is a problem with WPF or my graphics driver so that I can report it to the appropriate company. I have a Quadro FX 1700 with the latest drivers (197.54) on a Windows XP system, running a .NET 3.5 SP1 application.

I have dual monitors, my primary on the left and secondary on the right. The problem occurs when I maximize then restore a child window of the main window on my primary monitor. The child window is sized correctly on the primary monitor, but it is drawn on my secondary monitor as if it were still maximized. Moving the child window around on the primary monitor moves it on the secondary one.

Restored child window is drawn on secondary monitor as if it were still maximized

I made a sample application (code is below) which induces this behavior.

  1. Start the application and ensure the main window is on your primary monitor.
  2. Double-click the main window. A green child window should appear.
  3. Click the green child window to maximize.
  4. Click the green child window to restore.

Can anyone else reproduce this problem? On my system the green child restores, but then it's drawn on both my primary and secondary monitors, rather than just the primary monitor.

App.xaml

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="DualMonitorBug.App"
    StartupUri="Shell.xaml" />

App.xaml.cs

using System.Windows;
namespace DualMonitorBug { public partial class App : Application { } }

Shell.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="DualMonitorBug.Shell"
    Title="Shell" Height="480" Width="640"
    MouseDoubleClick="ShowDialog" />

Shell.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace DualMonitorBug
{
    public partial class Shell : Window
    {
        public Shell()
        {
            InitializeComponent();
        }

        private void ShowDialog(object sender, MouseButtonEventArgs e)
        {
            DialogWindow dialog = new DialogWindow();
            dialog.Owner = this;
            dialog.Show();
        }
    }
}

DialogWindow.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="DualMonitorBug.DialogWindow"
    Title="Dialog Window" Height="240" Width="320"
    AllowsTransparency="True"
    Background="Green"
    MouseLeftButtonDown="ShowHideDialog"
    WindowStyle="None" />

DialogWindow.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace DualMonitorBug
{
    public partial class DialogWindow : Window
    {
        public DialogWindow() { InitializeComponent(); }

        private void ShowHideDialog(object sender, MouseButtonEventArgs e)
        {
           if (e.ClickCount == 1)
           {
               if (this.WindowState == WindowState.Normal)
               {
                   this.DragMove();
               }
           }
           else
           {
               this.WindowState
                   = (this.WindowState == WindowState.Normal)
                   ? WindowState.Maximized
                   : WindowState.Normal;
           }
        }
    }
}
+1  A: 

Your app works fine on my system. I'm running dual monitors, 3.5SP1, but I have a Radeon HD4670.

Dave
Thanks for testing it out Dave. I filed a report with NVIDIA.
emddudley
np, hope you get it sorted out!
Dave
A: 

I have the same problem too. I don't think this is a graphic card problem because I tried it on my desktop and then my laptop with extended monitor and always see the extra maximized window on the second monitor after normalizing the real window. If graphic involved here, I would say it involved in the way that WPF was not designed to be compatible with all graphic cards.

This only happens when I use customized maximize/minimize buttons and set the WindowState based on the button click events. If I maximize the window using Windows default buttons, everything is ok. I was frustrated with finding a solution for this problem so I wrote some code to do maximize/normalize by changing the window size.

Tung
A: 

OK, I try something today and it seems the problem happens because the maximizing activity extends the width to the second monitor before moving the window to top-left corner. Therefore, when you normalize the window, the extended part is still in the second monitor and will not be cleared until you drag the window to the second monitor.

To work around this problem, before setting WindowState to Maximized, set Width and Height to zeros first. That will solve the problem. You may want to cache the current Top and Left so that when the window is normalized, it comes back to previous position:

Maximized code:

 _oldTop = Top;
_oldHeight = Height;
 Top = Height = 0;
 WindowState = WindowState.Maximized;

Normalized code:

Top = _oldTop;
Height = _oldHeight;
WindowState = WindowState.Normal;
Tung