How to get the size of the current screen in WPF?
I created a little wrapper around the Screen from System.Windows.Forms, currently everything works... Not sure about the "device independent pixels", though.
public class WpfScreen
{
public static IEnumerable<WpfScreen> AllScreens()
{
foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
{
yield return new WpfScreen(screen);
}
}
public static WpfScreen GetScreenFrom(Window window)
{
WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window);
Screen screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle);
WpfScreen wpfScreen = new WpfScreen(screen);
return wpfScreen;
}
public static WpfScreen GetScreenFrom(Point point)
{
int x = (int) Math.Round(point.X);
int y = (int) Math.Round(point.Y);
// are x,y device-independent-pixels ??
System.Drawing.Point drawingPoint = new System.Drawing.Point(x, y);
Screen screen = System.Windows.Forms.Screen.FromPoint(drawingPoint);
WpfScreen wpfScreen = new WpfScreen(screen);
return wpfScreen;
}
public static WpfScreen Primary
{
get { return new WpfScreen(System.Windows.Forms.Screen.PrimaryScreen); }
}
private readonly Screen screen;
internal WpfScreen(System.Windows.Forms.Screen screen)
{
this.screen = screen;
}
public Rect DeviceBounds
{
get { return this.GetRect(this.screen.Bounds); }
}
public Rect WorkingArea
{
get { return this.GetRect(this.screen.WorkingArea); }
}
private Rect GetRect(Rectangle value)
{
// should x, y, width, height be device-independent-pixels ??
return new Rect
{
X = value.X,
Y = value.Y,
Width = value.Width,
Height = value.Height
};
}
public bool IsPrimary
{
get { return this.screen.Primary; }
}
public string DeviceName
{
get { return this.screen.DeviceName; }
}
}
Here budy. This will give you only the width and height of the workarea
System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height
I also needed the current screen dimension, specifically the Work-area, which returned the rectangle excluding the Taskbar width.
I used it in order to reposition a window, which is opened to the right and down to where the mouse is positioned. Since the window is fairly large, in many cases it got out of the screen bounds. The following code is based on @e-j answer: This will give you the current screen.... The difference is that I also show my repositioning algorithm, which I assume is actually the point.
The code:
using System.Windows;
using System.Windows.Forms;
namespace MySample
{
public class WindowPostion
{
/// <summary>
/// This method adjust the window position to avoid from it going
/// out of screen bounds.
/// </summary>
/// <param name="topLeft">The requiered possition without its offset</param>
/// <param name="maxSize">The max possible size of the window</param>
/// <param name="offset">The offset of the topLeft postion</param>
/// <param name="margin">The margin from the screen</param>
/// <returns>The adjusted position of the window</returns>
System.Drawing.Point Adjust(System.Drawing.Point topLeft, System.Drawing.Point maxSize, int offset, int margin)
{
Screen currentScreen = Screen.FromPoint(topLeft);
System.Drawing.Rectangle rect = currentScreen.WorkingArea;
// Set an offset from mouse position.
topLeft.Offset(offset, offset);
// Check if the window needs to go above the task bar,
// when the task bar shadows the HUD window.
int totalHight = topLeft.Y + maxSize.Y + margin;
if (totalHight > rect.Bottom)
{
topLeft.Y -= (totalHight - rect.Bottom);
// If the screen dimensions exceed the hight of the window
// set it just bellow the top bound.
if (topLeft.Y < rect.Top)
{
topLeft.Y = rect.Top + margin;
}
}
int totalWidth = topLeft.X + maxSize.X + margin;
// Check if the window needs to move to the left of the mouse,
// when the HUD exceeds the right window bounds.
if (totalWidth > rect.Right)
{
// Since we already set an offset remove it and add the offset
// to the other side of the mouse (2x) in addition include the
// margin.
topLeft.X -= (maxSize.X + (2 * offset + margin));
// If the screen dimensions exceed the width of the window
// don't exceed the left bound.
if (topLeft.X < rect.Left)
{
topLeft.X = rect.Left + margin;
}
}
return topLeft;
}
}
}
Some explanations:
1) topLeft - position of the top left at the desktop (works
for multi screens - with different aspect ratio).
Screen1 Screen2
â ââââââââââââââââââââââââââââââââââââââââââ Screen3
â² â ââ ââââââââââââââââââââ â
â â ââ ââ â¼- â â²
1080 â â ââ ââ â â
â â ââ ââ â â 900
â¼ â ââ ââ â â¼
â ââââââââ¬ââââââ¬âââââââââââââââ¬ââââââ¬âââââââââââââââ¬âââââ¬ââââââ â
ââ´ââââââ´â ââ´ââââââ´â ââ´âââââ´â
ââââââââââââââââââââºâââââââââââââââââââââºâââââââââââââââââââºâ
1920 1920 1440
If the mouse is in Screen3 a possible value might be:
topLeft.X=4140 topLeft.Y=195
2) offset - the offset from the top left, one value for both
X and Y directions.
3) maxSize - the maximal size of the window - including its
size when it is expanded - from the following example
we need maxSize.X = 200, maxSize.Y = 150 - To avoid the expansion
being out of bound.
Non expanded window:
ââââââââââââââââââââââââââââââââ â
â Window Name [X]â â²
âââââââââââââââââââââââââââââââ⤠â
â âââââââââââââââââââ â â 100
â Text1: â â â â
â âââââââââââââââââââ â â
â [â¼] â â¼
ââââââââââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââºâ
200
Expanded window:
ââââââââââââââââââââââââââââââââ â
â Window Name [X]â â²
âââââââââââââââââââââââââââââââ⤠â
â âââââââââââââââââââ â â
â Text1: â â â â
â âââââââââââââââââââ â â 150
â [â²] â â
â âââââââââââââââââââ â â
â Text2: â â â â
â âââââââââââââââââââ â â¼
ââââââââââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââºâ
200
4) margin - The distance the window should be from the screen
work-area - Example:
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â â Margin
â â â
â â
â â
â â
â ââââââââââââââââââââââââââââââââ â
â â Window Name [X]â â
â âââââââââââââââââââââââââââââââ⤠â
â â âââââââââââââââââââ â â
â â Text1: â â â â
â â âââââââââââââââââââ â â
â â [â²] â â
â â âââââââââââââââââââ â â
â â Text2: â â â â
â â âââââââââââââââââââ â â
â ââââââââââââââââââââââââââââââââ â â
â â â Margin
ââââââââââââââââââââââââââââââââââââââââââââââââââââ¬ââââââââââ⤠â
â[start] [â ][â¦][â£][â¥] âenâ 12:00 â
ââââââââââââââââââââââââââââââââââââââââââââââââââââ´âââââââââââ
ââââºâ ââââºâ
Margin Margin
* Note that this simple algorithm will always want to leave the cursor
out of the window, therefor the window will jumps to its left:
âââââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââââââ
â â¼-ââââââââââââââââ â âââââââââââââââââ¼- â
â â Window [X]â â â Window [X]â â
â âââââââââââââââ⤠â âââââââââââââââ⤠â
â â âââââ â â â âââââ â â
â â Val: â â â -> â â Val: â â â â
â â âââââ â â â âââââ â â
â ââââââââââââââââ â ââââââââââââââââ â
â â â â
ââââââââââââââââââââââââ¬ââââââââââ⤠ââââââââââââââââââââââââ¬âââââââââââ¤
â[start] [â ][â¦][â£] âenâ 12:00 â â[start] [â ][â¦][â£] âenâ 12:00 â
ââââââââââââââââââââââââ´âââââââââââ ââââââââââââââââââââââââ´âââââââââââ
If this is not a requirement, you can add a parameter to just use
the margin:
âââââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââââââ
â â¼-ââââââââââââââââ â âââ¼-ââââââââââââ â
â â Window [X]â â â Window [X]â â
â âââââââââââââââ⤠â âââââââââââââââ⤠â
â â âââââ â â â âââââ â â
â â Val: â â â -> â â Val: â â â â
â â âââââ â â â âââââ â â
â ââââââââââââââââ â ââââââââââââââââ â
â â â â
ââââââââââââââââââââââââ¬ââââââââââ⤠ââââââââââââââââââââââââ¬âââââââââââ¤
â[start] [â ][â¦][â£] âenâ 12:00 â â[start] [â ][â¦][â£] âenâ 12:00 â
ââââââââââââââââââââââââ´âââââââââââ ââââââââââââââââââââââââ´âââââââââââ
* Supports also the following scenarios:
1) Screen over screen:
âââââââââââââââââââ
â â
â â
â â
â â
âââââââââââââââââââ
âââââââââââââââââââââ
â â
â â¼- â
â â
â â
â â
ââââââââ¬ââââââ¬âââââââ
ââ´ââââââ´â
2) Window bigger than screen hight or width
âââââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââââââ
â â â ââââââââââââââââ â
â â â â Window [X]â â
â â¼-ââââââââââââââââ â âââââââââââââââ⤠â¼- â
â â Window [â]â â â âââââ â â
â âââââââââââââââ⤠-> â â Val: â â â â
â â ââââââ â â â âââââ â â
â â Val: â ââ â â â âââââ â â
â â ââââââ â â â Val: â â â â
ââââââââââââââââââââââââ¬ââââââââââ⤠â ââââââââââââââââââââââââ¬âââââââââââ¤
â[start] [â ][â¦][â£] âenâ 12:00 â â â[start] [â ][â¦][â£] âenâ 12:00 â
ââââââââââââââââââââââââ´âââââââââââ â ââââââââââââââââââââââââ´âââââââââââ
â âââââ â â âââââ â
â Val: â â â ââââââââââââââââ
â âââââ â
ââââââââââââââââ
âââââââââââââââââââââââââââââââââââ âââââââââââââââââââââââââââââââââââ
â â â â
â â â âââââââââââââââââââââââââââââââââââââ
â â¼-âââââââââââââââââââââââââââââââââââââ â â Wâ¼-dow â[X]â
â â Window â [X]â â âââââââââââââââââââââââââââââââââââââ¤
â ââââââââââââââââââââââââââââââââââââ⤠â â âââââ âââââ âââ¤ââ â
â â âââââ âââââ â âââââ â -> â â Val: â â Val: â â Val: â â â â
â â Val: â â Val: â â Vaâ: â â â â â âââââ âââââ âââ¤ââ â
â â âââââ âââââ â âââââ â â âââââââââââââââââââââââââââââââââââââ
ââââââââââââââââââââââââ¬âââââââââââ¤âââââââââ ââââââââââââââââââââââââ¬âââââââââââ¤
â[start] [â ][â¦][â£] âenâ 12:00 â â[start] [â ][â¦][â£] âenâ 12:00 â
ââââââââââââââââââââââââ´âââââââââââ ââââââââââââââââââââââââ´âââââââââââ
- I had no choice but using the code format (otherwise the white spaces would have been lost).
- Originally this appeared in the code above as a
<remark><code>...</code></remark>
This will give you the current screen based on the top left of the window just call this.CurrentScreen() to get info on the current screen.
using System.Windows;
using System.Windows.Forms;
namespace Common.Helpers
{
public static class WindowHelpers
{
public static Screen CurrentScreen(this Window window)
{
return Screen.FromPoint(new System.Drawing.Point((int)window.Left,(int)window.Top));
}
}
}