I am working on WPF application and I faced problem that when WindowStyle=None
and WindowState = WindowState.Maximized
the application goes under top or left placed taskbar.
When taskbar is placed bottom or right all works normal.
I know about Left
and Top
properties of window, but they are ignored in Maximized
state.
Also there is Microsoft.Windows.Shell.WindowСhrome
that gives ability to drag, double click to maximize and restore, snap and unsnap. (it is need to be added as dll reference)
I want to achieve that my application don't hide or go under taskbar and works correctly with behavior that WindowСhrome
provide.
MainWindow.xaml
<Window x:Class="WpfAppTestFullScreen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
WindowStyle="None"
Title="MainWindow" Height="350" Width="525"
Left="100" Top="100">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="{Binding ActualHeight,ElementName=topBarGrid}"/>
</WindowChrome.WindowChrome>
<Grid x:Name="mainGrid" Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="topBarGrid" Grid.Row="0" >
<Border BorderBrush="Black" BorderThickness="1" >
<DockPanel x:Name="panelForWindowControls"
VerticalAlignment="Stretch"
DockPanel.Dock="Right"
LastChildFill="False"
>
<Button Name="buttonExit"
Width="43" Height="28"
Margin="0" Click="buttonExit_Click"
DockPanel.Dock="Right" Content="x"
WindowChrome.IsHitTestVisibleInChrome="True"
/>
<Button Name="buttonMax"
Width="43" Height="28"
Margin="0" Click="buttonMax_Click"
DockPanel.Dock="Right" Content="[]"
WindowChrome.IsHitTestVisibleInChrome="True"
/>
<Button Name="buttonMin"
Width="43" Height="28"
Margin="0" Click="buttonMin_Click"
DockPanel.Dock="Right" Content="_"
WindowChrome.IsHitTestVisibleInChrome="True"
/>
</DockPanel>
</Border>
</Grid>
<Grid x:Name="bodyGrid" Grid.Row="1">
<Button Content="FullScreen" x:Name="FullScreenButton"
Height="50" Width="200"
HorizontalAlignment="Center" VerticalAlignment="Center"
Click="FullScreenButton_Click" />
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
namespace WpfAppTestFullScreen
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
}
private void FullScreenButton_Click(object sender, RoutedEventArgs e)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
private void buttonMax_Click(object sender, RoutedEventArgs e)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
private void buttonMin_Click(object sender, RoutedEventArgs e)
{
WindowState = (WindowState == WindowState.Minimized) ? WindowState.Normal : WindowState.Minimized;
}
private void buttonExit_Click(object sender, RoutedEventArgs e)
{
}
}
}
A better approach would be to use a couple of native methods from the
User32.dll
(taken from this blog post)
How it works:
WindowProc
) so you can receive window messages from the system.0x24
=WM_GETMINMAXINFO
) that the window size is about to be changedMonitorFromWindow
) and update the bounds.So, no matter how the Window is resized (drag to top of screen, windows key + arrows, maximize button, etc.) it will stay within the boundary of your workarea.
Native Methods and Types:
(just copy this class into your project)
Your Window: