I am using window form with borderstyle = none.
When I use the following code to maximize my window, it maximizes so that it covers the traybar.
private void pb_max_Click(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Maximized)
{
WindowState = FormWindowState.Normal;
pb_max.Image = GomeeSoft.Properties.Resources.buttonmax;
}
else
{
WindowState = FormWindowState.Maximized;
pb_max.Image = GomeeSoft.Properties.Resources.buttonreturn;
}
}
How do you maximize safely so that the frame is maximized only in the workspace?
Perhaps something like this:
this.MaximumSize = Screen.PrimaryScreen.WorkingArea.Size;
From MSDN:
The working area is the desktop area of the display,
excluding taskbars, docked windows, and docked tool bars.
Related
I have an option to start my mainwindow minimized. The window is set to SizeToContent="WidthAndHeight". when I click to restore the window it opens larger than the initial WidthAndHeight. I use the following in the MainWindow.xaml.cs
private void WindowStart()
{
if (LocalSystem.StartMinimized)
{
WindowState = WindowState.Minimized;
ShowInTaskbar = true;
}
if (LocalSystem.StartOnTop)
{
Topmost = true;
}
Activate();
}
Consider keeping track of the state change of your WPF window. Add an event handler of the StateChanged event of your Window and keep track of the Window width and height.
You could keep track of the size of the window like this:
public MainWindow() {
InitializeComponent();
_lastState = this.WindowState;
_initialWidth = this.ActualWidth;
_initialHeight = this.ActualHeight;
this.StateChanged += Window_StateChanged;
}
WindowState _lastState;
double _initialwidth, _initialHeight;
private void Window_StateChanged(object sender, EventArgs e)
{
if (this.WindowState != _lastState)
{
if (_lastState == WindowState.Minimized && this.WindowState == WindowState.Maximized){
this.Width = _initialWidth;
this.Height = _initialHeight;
}
_lastState = this.WindowState;
}
}
Note the use of ActualHeight and ActualWidth. The Window actual dimensions will be known after InitializeComponent is run inside its constructor. A restored or unminized, as you so eloquently put it, window is window where the State goes from WindowState.Minimized to WindowState.Maximized.
Note that we try to minimize the amount of code behind in WPF apps, as a best practice is to use MVVM. You could though consider creating a WPF behavior class for restoring initial size of Window, after all it is a generic behavior.
How can you program a dotNet Windows (or WPF) Application in order to let it going fullscreen on the secondary monitor?
Extension method to Maximize a window to the secondary monitor (if there is one).
Doesn't assume that the secondary monitor is System.Windows.Forms.Screen.AllScreens[2];
using System.Linq;
using System.Windows;
namespace ExtendedControls
{
static public class WindowExt
{
// NB : Best to call this function from the windows Loaded event or after showing the window
// (otherwise window is just positioned to fill the secondary monitor rather than being maximised).
public static void MaximizeToSecondaryMonitor(this Window window)
{
var secondaryScreen = System.Windows.Forms.Screen.AllScreens.Where(s => !s.Primary).FirstOrDefault();
if (secondaryScreen != null)
{
if (!window.IsLoaded)
window.WindowStartupLocation = WindowStartupLocation.Manual;
var workingArea = secondaryScreen.WorkingArea;
window.Left = workingArea.Left;
window.Top = workingArea.Top;
window.Width = workingArea.Width;
window.Height = workingArea.Height;
// If window isn't loaded then maxmizing will result in the window displaying on the primary monitor
if ( window.IsLoaded )
window.WindowState = WindowState.Maximized;
}
}
}
}
For WPF apps look at this post. Ultimately it depends on when the WindowState is set to Maximized. If you set it in XAML or in window constructor (i.e. before the window is loaded) it will always be maximized onto primary display. If, on the other hand, you set WindowState to Maximized when the window is loaded - it will maximise on the screen on which it was maximized before.
I notice an answer which advocates setting the position in the Loaded event, but this causes flicker when the window is first shown normal then maximized. If you subscribe to the SourceInitialized event in your constructor and set the position in there it will handle maximizing onto secondary monitors without flicker - I'm assuming WPF here
public MyWindow()
{
SourceInitialized += MyWindow_SourceInitialized;
}
void MyWindow_SourceInitialized(object sender, EventArgs e)
{
Left = 100;
Top = 50;
Width = 800;
Height = 600;
WindowState = WindowState.Maximized;
}
Substitute coords for any on your secondary monitor
See this codeproject article.
The code in there will work, but default to your primary monitor. To change this, you'll need to replace the calls to GetSystemMetrics will calls to GetMonitorInfo. Using GetMonitorInfo, you can get the appropriate RECT to pass to SetWindowPos.
GetMonitorInfo allows you to get the RECT for any monitor.
There is an MSDN Article on Position Apps in Multi-Monitor Setups that might help explain things a bit better.
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.None;
this.Bounds = GetSecondaryScreen().Bounds;
}
private Screen GetSecondaryScreen()
{
foreach (Screen screen in Screen.AllScreens)
{
if (screen != Screen.PrimaryScreen)
return screen;
}
return Screen.PrimaryScreen;
}
It's not clear from your question if you are looking for a way to move the window to the secondary monitor and then go fullscreen, or if you are just looking to support fullscreen mode on whatever monitor the window is on (which may be primary or secondary).
If the later, for a WPF window, though not quite the same as fullscreen mode, you can remove the borders when it is maximized and restore the border when not maximized. No need to check for which monitor, etc. The display of the caption/title bar is controlled by the border state.
protected override void OnStateChanged(EventArgs e)
{
if (WindowState == WindowState.Maximized)
{
if (WindowStyle.None != WindowStyle)
WindowStyle = WindowStyle.None;
}
else if (WindowStyle != WindowStyle.SingleBorderWindow)
WindowStyle = WindowStyle.SingleBorderWindow;
base.OnStateChanged(e);
}
Credit goes to Pavel for his Forms-based answer in the current question and to Nir for his answer in this question.
#jay-evans answer did the trick for me. However, I also needed to add the WpfscreenHelper Nuget package to get the screen information while not depending on the old System.Windows.Forms namespace as in #grantnz's answer.
Also note that setting the dimensions only (left, top, width + height) left me with a small border on each side. Only after setting WindowState.Maximized is it that the real full-screen effect was achieved.
Since I have monitors with varying DPI configurations, I also had to use WpfWorkingArea instead of WorkingArea, since the coordinates were coming back incorrectly.
Posting here for completeness, this is using WPF with .NET 7.0 and is confirmed to work with varying DPI configurations:
public MainWindow()
{
InitializeComponent();
SourceInitialized += MainWindow_SourceInitialized;
}
private void MainWindow_SourceInitialized(object? sender, EventArgs e)
{
var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(s => !s.Primary);
if (screen != null)
{
this.WindowState = WindowState.Normal;
this.Left = screen.WpfWorkingArea.Left;
this.Top = screen.WpfWorkingArea.Top;
this.Width = screen.WpfWorkingArea.Width;
this.Height = screen.WpfWorkingArea.Height;
this.WindowState = WindowState.Maximized;
}
}
In WPF: Set the WindowState property in Normal (not Maximixed) and create the event Loaded. In the event write this code:
this.Left = SystemParameters.PrimaryScreenWidth + 100;
this.WindowState = System.Windows.WindowState.Maximized;
I have a line of code to forbid all possibilities to resize the window of my application.
this.ResizeMode = ResizeMode.NoResize;
Through this the maximize and minimize button on the top right of the window are not shown and you cannot maximize the window by double clicking the menubar.
I thought it works but then I found out that you can minimize the window with a double click on the menubar. I was very confused that this is possible. Has someone an answer to this question that you can not maximize the window with the double click but it is possible to minimize it?
You can easily prevent minimization my detecting the change with the Resize event and setting it back to its original size.
NOTE: You will see the window minimize briefly and then come back.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Resize += new EventHandler(Form1_Resize);
}
void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.WindowState = FormWindowState.Normal;
}
}
}
I have a WinForms application, which is set to full screen mode when I login.
My problem is it's covering the Windows taskbar also. I don't want my application to cover the taskbar.
How can this be done?
The way I do it is via this code:
this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
this.WindowState = FormWindowState.Maximized;
This is probably what you want. It creates a 'maximized' window without hiding the taskbar.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load( object sender, EventArgs e )
{
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Left = Top = 0;
Width = Screen.PrimaryScreen.WorkingArea.Width;
Height = Screen.PrimaryScreen.WorkingArea.Height;
}
}
I had answer it here:
One thing I left out of the description--I'd turned off the maximize button. When I tested turning that property back on, the task bar showed up again. Apparently it assumes if you don't want a maximize button you are creating a kiosk-style application where you don't want your users to see anything but the application screen. Not exactly what I'd expect, but works I guess.
I had this problem and solved it by Jeff's help. First, set the windowstate to Maximized. but Do not disable the MaximizeBox. Then if you want MaximizeBox to be disabled you should do it programmatically:
private void frmMain_Load(object sender, EventArgs e)
{
this.MaximizeBox = false;
}
Arcanox's answer is great for a single monitor, but if you try it on any screen other than the leftmost, it will just make the form disappear. I used the following code instead.
var workingArea = Screen.FromHandle(Handle).WorkingArea;
MaximizedBounds = new Rectangle(0, 0, workingArea.Width, workingArea.Height);
WindowState = FormWindowState.Maximized;
The only difference is I'm overriding the top & left values to be 0, 0 since they will be different on other screens.
If you have multiple screens, you have to reset location of MaximizedBounds :
Rectangle rect = Screen.FromHandle(this.Handle).WorkingArea;
rect.Location = new Point(0, 0);
this.MaximizedBounds = rect;
this.WindowState = FormWindowState.Maximized;
I'm not good at explaining but this is the code I used to maximize or to full screen the winforms which would not cover up the taskbar. Hope it helps. ^^
private void Form_Load(object sender, EventArgs e)
{
this.Height = Screen.PrimaryScreen.WorkingArea.Height;
this.Width = Screen.PrimaryScreen.WorkingArea.Width;
this.Location = Screen.PrimaryScreen.WorkingArea.Location;
}
If you want to use WindowState = Maximized;, you should first indicate the size limits of the form maximized by the MaximizedBounds property...
Example:
MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
WindowState = FormWindowState.Maximized;
Where are you limiting the size of your form to the work area that is the desktop area of the display
If Maximizing isn't what you're looking for, then you'll need to calculate the window size yourself by checking for the location and size of the taskbar:
find-out-size-and-position-of-the-taskbar
Try without FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; and comment line like :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load( object sender, EventArgs e )
{
// FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Left = Top = 0;
Width = Screen.PrimaryScreen.WorkingArea.Width;
Height = Screen.PrimaryScreen.WorkingArea.Height;
}
}
private void frmGateEntry_Load(object sender, EventArgs e)
{
// set default start position to manual
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
// set position and size to the Form.
this.Bounds = Screen.PrimaryScreen.WorkingArea;
}
This was very useful to me:
private void Form1_Load(object sender, EventArgs e)
{
this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
this.WindowState = FormWindowState.Maximized;
}
I know it's a bit too late, but it will help others too in the future.
the answered code above is working but still in my case if the taskbar is auto-hiding and showing it wont show the taskbar once it hides from the screen. I solved this problem by adding -1` to the working area height.
var workingArea = Screen.FromHandle(Handle).WorkingArea;
MaximizedBounds = new Rectangle(0, 0, workingArea.Width, workingArea.Height - 1);
Consider the following code:
Window myWindow = new MyWindowSubclass();
myWindow.BringIntoView();
myWindow.Show();
// Code which is effective as pressing the maximize button
Also, how to detect if the window is indeed in maximized state.
In WPF, you can use the WindowState property:
myWindow.WindowState = WindowState.Maximized;
You can of course query that property to obtain the current window state:
if (myWindow.WindowState == WindowState.Maximized) {
// Window is currently maximized.
}
For WinForms, you can use
bool maximized = this.WindowState == System.Windows.Forms.FormWindowState.Maximized;
to test if the window is maximized.
The SizeChanged and Resize events should capture all changes to the window state.
In WinForms, do
// Code which is effective as pressing the maximize button
myWindow.WindowState = FormWindowState.Maximized;
Of course you can test it the same way:
if (myWindow.WindowState == FormWindowState.Maximized) { ... }