WPF : Maximize window with WindowState Problem (application will hide windows taskbar)

Viewed 29611

I have set my main window state to "Maximized" but the problem is my application will fill the whole screen even task bar. what am i doing wrong ? I'm using windows 2008 R2 with resolution : 1600 * 900

Here is the Xaml :

<Window x:Class="RadinFarazJamAutomationSystem.wndMain"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:RadinFarazJamAutomationSystem"
     xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="MyName"  FontFamily="Tahoma" FontSize="12" Name="mainWindow"  WindowState="Maximized"   xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
    xmlns:my="clr-namespace:RadinFarazJamAutomationSystem.Calendare.UC" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  Loaded="mainWindow_Loaded" FlowDirection="LeftToRight"
    ResizeMode="NoResize" Closed="mainWindow_Closed">
7 Answers

This one works the best...

public MainWindow()
    {
        InitializeComponent();
        MaxHeight = SystemParameters.VirtualScreenHeight;
        MaxWidth = SystemParameters.VirtualScreenWidth;
    }

I've implemented solution which considers multiple displays case based on the Mike Weinhardt answer in the thread. If you want to maximize/minimize window programmatically with your own buttons you can use this.

Solution:

// To get a handle to the specified monitor
[DllImport("user32.dll")]
private static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags);

// To get the working area of the specified monitor
[DllImport("user32.dll")]
private static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out] MonitorInfoEx monitorInfo);

private static MonitorInfoEx GetMonitorInfo(Window window, IntPtr monitorPtr) {
    var monitorInfo = new MonitorInfoEx();

    monitorInfo.cbSize = Marshal.SizeOf(monitorInfo);
    GetMonitorInfo(new HandleRef(window, monitorPtr), monitorInfo);

    return monitorInfo;
}

private static void Minimize(Window window) {
     if(window == null) {
         return;
     }

     window.WindowState = WindowState.Minimized;
 }

 private static void Restore(Window window) {
        if(window == null) {
            return;
        }

        window.WindowState = WindowState.Normal;
        window.ResizeMode = ResizeMode.CanResizeWithGrip;
    }

    private static void Maximize(Window window) {
        window.ResizeMode = ResizeMode.NoResize;

        // Get handle for nearest monitor to this window
        var wih = new WindowInteropHelper(window);

        // Nearest monitor to window
        const int MONITOR_DEFAULTTONEAREST = 2;
        var hMonitor = MonitorFromWindow(wih.Handle, MONITOR_DEFAULTTONEAREST);

        // Get monitor info
        var monitorInfo = GetMonitorInfo(window, hMonitor);

        // Create working area dimensions, converted to DPI-independent values
        var source = HwndSource.FromHwnd(wih.Handle);

        if(source?.CompositionTarget == null) {
            return;
        }

        var matrix = source.CompositionTarget.TransformFromDevice;
        var workingArea = monitorInfo.rcWork;

        var dpiIndependentSize =
            matrix.Transform(
                new Point(workingArea.Right - workingArea.Left,
                          workingArea.Bottom - workingArea.Top));



        // Maximize the window to the device-independent working area ie
        // the area without the taskbar.
        window.Top = workingArea.Top;
        window.Left = workingArea.Left;

        window.MaxWidth = dpiIndependentSize.X;
        window.MaxHeight = dpiIndependentSize.Y;

        window.WindowState = WindowState.Maximized;
    }

Auxilary structs:

// Rectangle (used by MONITORINFOEX)
[StructLayout(LayoutKind.Sequential)]
public struct Rect {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

// Monitor information (used by GetMonitorInfo())
[StructLayout(LayoutKind.Sequential)]
public class MonitorInfoEx {
    public int cbSize;
    public Rect rcMonitor; // Total area
    public Rect rcWork; // Working area
    public int dwFlags;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
    public char[] szDevice;
}

p.s. to hide default buttons use:

WindowStyle="None"

in the window XAML.

You can set MaxHeight property in the xaml code, like that:

 MaxHeight="{x:Static SystemParameters.MaximizedPrimaryScreenHeight}"

I wanted the opposite (with WindowStyle=None), but reversing this solution also works for your case:

// prevent it from overlapping the taskbar

// "minimize" it
WindowStyle = WindowStyle.SingleBorderWindow;
// Maximize it again. This time it will respect the taskbar.
WindowStyle = WindowStyle.None;
WindowState = WindowState.Maximized;
// app is now borderless fullscreen, showing the taskbar again

What I did for my case:

// make it always overlap the taskbar

// From windowed to maximized without border and window bar
WindowStyle = WindowStyle.None;
WindowState = WindowState.Maximized;
// Now the window does not overlap the taskbar
Hide();
Show();
// Now it does (because it's re-opened)
Related