2

If I create an empty WPF application from the Visual Studio template and set the window sizes to the resolution of my device, when I maximize the window I see a black strip on the right where it appears a scrollbar would be rendered (but is not and should not be). Also see the same on the bottom. Note the title bar is the correct maximized width so I assume this is all client area rendering issues.

I removed the default Grid control that comes with the template, so the XAML here is bare bones. In this case I am targeting a display with resolution 1366x768. Maximize this window in a display set to 1366x768 to see the issue (or change the vals to your display resolution)

Here is the MainWindow.xaml code. The MainWindow.xaml.cs is untouched default template code.

<Window x:Class="TestMaximize.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" 
        Width="1366"
        Height="768"
        MaxWidth="1366"
        MaxHeight="768" >
</Window>

What is causing those phantom scrollbar areas and how do I prevent this?

Thanks for any thoughts about this.

Rob Campbell
  • 451
  • 4
  • 10

1 Answers1

1

The reason is that you are setting MaxWidth to be too small when it's maximized.

If the window is maximized, the size of Window will be 1382 x 744 (in order to "go to fullscreen". That's basically (1366 + 2*ClientWIndowEdges) x (768 - some amount stripped away from titlebar and bottom).

You are forcing window to be 1366x768 when it's maximized, thus the actual Border inside Window will get less space, 1350x760 or something..

You can remove the MaxWidth and MaxHeight constraint when your window is maximized:

<Window x:Class="myNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Style>
        <Style TargetType="Window">
            <Style.Setters>
                <Setter Property="MaxWidth" Value="1366" />
                <Setter Property="MaxHeight" Value="768"></Setter>

            </Style.Setters>

            <Style.Triggers>
                <Trigger Property="WindowState" Value="Maximized">
                    <Setter Property="MaxWidth" Value="9999" />
                    <Setter Property="MaxHeight" Value="9999"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Style>

    <Grid Background="LightBlue"></Grid>
</Window>

However, I suspect that is not what you want. You actually want to have constraints, when your Window is maximized. For this, I suggest to use code-behind:

private readonly int _maxHeight = 760;
private readonly int _maxWidth = 1366;

public MainWindow()
{
    InitializeComponent();

    DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty
          (WindowStateProperty, typeof (MainWindow));

    dpd.AddValueChanged(this, (sender, args) =>
    {
        if (WindowState == WindowState.Maximized)
        {
            var interopHelper = new WindowInteropHelper(this);
            var barInfo = PInvokeWrapper.GetTitleBarInfoEx(interopHelper.Handle);

            var borderWidth = barInfo.rcTitleBar.Left;

            MaxWidth = _maxWidth + borderWidth;
        }
        else
        {
            MaxWidth = _maxWidth;
            MaxHeight = _maxHeight;
        }
    });

    WindowState = WindowState.Normal;
 }

The idea is simple, if window is maximized, we recalculate the MaxWidth property, including the frame width. I chopped that together with few minutes, it needs debugging through multiple machines to make sure it works everywhere, but it looks 'okayish' to me.

For GetTitleBarInfoEx, you might want to check this thread: How do I compute the non-client window size in WPF?

Community
  • 1
  • 1
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78