How to determine the screen width/height using C# - c#

I want to set the width & height of a Window dynamically based on the user screens maximum width/height. How can I determine this programmatically?

For the primary screen:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
(Note that there are also some other primary screen related properties which depend on various factors, Full* & Maximised*)
Virtual screen:
SystemParameters.VirtualScreenWidth
SystemParameters.VirtualScreenHeight

If you want the specific dimensions of the monitor your program is running on (if someone is running more than one monitor) you could also use:
var helper = new WindowInteropHelper(this); //this being the wpf form
var currentScreen = Screen.FromHandle(helper.Handle);
This will return a screen object referencing the monitor the program is running on. From there you can use the currentScreen.Bounds.Width / Height property (for the full size) or the currentScreen.WorkingArea.Width / Height (minus task bar, etc.) depending on what you want.

use Screen Object
Screen.PrimaryScreen.Bounds.Width

I couldn't use any of the solutions above under .NET 4.0.30319.42000 with Windows 10 Enterprise when calling it from the Ranorex Studio 8.0.1+git.8a3e1a6f, so I used the line
using WinForms = System.Windows.Forms;
[…]
SetWindowPos(processes[0].MainWindowHandle,
0,
y,
x,
WinForms.SystemInformation.PrimaryMonitorSize.Width,
WinForms.SystemInformation.PrimaryMonitorSize.Height,
SWP.SHOWWINDOW);

You can use the SizeChanged event
SizeChanged="MyWindow_SizeChanged"
Then in your event handler,
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.MinWidth > 0 && this.MinHeight > 0)
{
double heightScaleFactor = e.NewSize.Height / this.MinHeight;
double widthScaleFactor = e.NewSize.Width / this.MinWidth;
mainGrid.LayoutTransform = new ScaleTransform(heightScaleFactor, widthScaleFactor);
}
}
where MainGrid is a container for all the contents in MyWindow.

You can get the screen height and width:
int height = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Height;
int width = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Width;
Then set the Window's Height and Width properties to those in the Initialization.
this.Height = height;
this.Width = width;
Works to get the screen's height and width in WinForms or in ASP .NET. No muss, no fuss, except you'll need to reference the System.Windows.Forms assembly in your project if it's not a WinForm project.

Related

WPF C# multiple monitors restoring position scaling at 125%

I am having a trouble restoring floating tools in Avalondock.
The app Im developing uses avalondock for document managements with a few tools.
I usually use the tools on the 2nd monitor.
I use multiple monitors at work with 125% scaling on one and 100% scaling on the other. The main monitor is 4k monitor, the other is 2k monitor.
When i remote desktop the work pc with a single monitor (3440x1440) and ran the app, i noticed that the tools in 2nd monitors are not visible and i have no way to bring them back to main screen.
Avalondock's floating LayoutAnchorables are not treated as separate views.
if any one knows how to make LayoutAnchorable as a separate windows view, that would be the best solution. But i could not find how to do it. I tried the following
if (args.Model.IsFloating)
{
var left = (int)args.Model.FloatingLeft;
var top = (int)args.Model.FloatingTop;
var width = (int)args.Model.FloatingWidth;
var height = (int)args.Model.FloatingHeight;
var rect = new System.Drawing.Rectangle(left, top, width, height);
var intersected = Screen.AllScreens.Any(p => p.WorkingArea.IntersectsWith(rect));
if (!intersected)
{
//need to reposition
args.Model.FloatingLeft = 0;
args.Model.FloatingTop = 0;
}
//args.Model.FloatingTop;
}
System.Windows.SystemParameters.PrimaryScreenHeight 1440 double
System.Windows.SystemParameters.PrimaryScreenWidth 3440 double
System.Windows.SystemParameters.VirtualScreenHeight 1440 double
System.Windows.SystemParameters.VirtualScreenWidth 3440 double
args.Model.FloatingLeft 4133.6 double
args.Model.FloatingTop 909.6 double
WorkingArea {X = 0 Y = 0 Width = 4300 Height = 1750} System.Drawing.Rectangle
The problem is that the working area is scaled at 125%.
This makes args.Model within the bounds of the main windows.
So i guess i can't use System.Windows.Forms.Screen info because i do not know which scaling the user will be using.
How do i get the real resolutions of the multiple monitors and positions and scaling?
i found the answer myself.
I was able to make the floating windows owner to null.
Apparently the dock's floatingwindow inherit from System.Windows.Window
This is what i wanted from the beginning.
private void DockManager_LayoutUpdated(object sender, EventArgs e)
{
foreach (var floatingWindow in dockManager.FloatingWindows)
{
if (floatingWindow.Owner != null)
{
floatingWindow.Owner = null;
}
floatingWindow.ShowInTaskbar = true;
}
}

Setting window size on desktop for a Windows 10 UWP app

I've just started learning UWP app development on Windows 10 Pro using Visual Studio 2015 Community Edition. I tried to modify the C# version of the official "Hello, World!" sample by setting the Width and Height attributes of the Page tag in MainPage.xaml.
Interestingly, when I start the app, its size will be different. Moreover, if I resize its window and then restart it, the app seems to remember its previous window size.
Is it possible to force a UWP app to have a predefined window size, at least on desktop PCs?
Try setting PreferredLaunchViewSize in your MainPage's constructor like this:
public MainPage()
{
this.InitializeComponent();
ApplicationView.PreferredLaunchViewSize = new Size(480, 800);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
As #kol also pointed out, if you want any size smaller than the default 500x320, you will need to manually reset it:
ApplicationView.GetForCurrentView().SetPreferredMinSize(new Size(200, 100));
You don't really have control over the window size, and even if you will try to re-size it it may fail. I've asked the same question on MSDN forums and got the answer here:
Windows 10 universal DirectX application
BTW, here is the solution in your event handler "OnLaunched" or in your Event Handler "OnActivated" find:
Window.Current.Activate();
And replace it with:
float DPI = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi;
Windows.UI.ViewManagement.ApplicationView.PreferredLaunchWindowingMode = Windows.UI.ViewManagement.ApplicationViewWindowingMode.PreferredLaunchViewSize;
var desiredSize = new Windows.Foundation.Size(((float)800 * 96.0f / DPI), ((float)600 * 96.0f / DPI));
Windows.UI.ViewManagement.ApplicationView.PreferredLaunchViewSize = desiredSize;
Window.Current.Activate();
bool result = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TryResizeView(desiredSize);
It is better if you place this code into the "OnActivated()" event handler as it will set your defined size when the app starts and when it becomes active after any interruptions.
In the "desiredSize" calculation, 800 is the width and 600 is the height. This calculation is needed, because the size is in DPI, so you have to convert it from pixels to DPI.
Also keep in mind that size cannot be smaller than "320x200".
For the very first app launch, the ApplicationView.PreferredLaunchWindowingMode is set to ApplicationViewWindowingMode.Auto regardless of what you set in your code.
However, from this question on MSDN, there may be a way to overcome this. One of the answers gives a way to set that very first launch size (reverting to Auto after that).
If your goal is to launch only once at a PreferredLaunchViewSize, you can use this rude solution (up to you for a better implementation with your coding style! :P)
public MainPage()
{
this.InitializeComponent();
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
if (localSettings.Values["launchedWithPrefSize"] == null)
{
// first app launch only!!
ApplicationView.PreferredLaunchViewSize = new Size(100, 100);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
localSettings.Values["launchedWithPrefSize"] = true;
}
// resetting the auto-resizing -> next launch the system will control the PreferredLaunchViewSize
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
}
}
P.S. I have not tested this.
In this other link here in StackOverflow, there is another way to do it: https://stackoverflow.com/a/68583688/5993426. This code is to insert in the App.xaml:
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
SetWindowMinSize(new Size(args.Window.Bounds.Width, args.Window.Bounds.Height));
args.Window.CoreWindow.SizeChanged += CoreWindow_SizeChanged;
base.OnWindowCreated(args);
}
private void CoreWindow_SizeChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.WindowSizeChangedEventArgs args)
{
if (SetWindowMinSize(args.Size))
{
sender.ReleasePointerCapture();
}
}
private bool SetWindowMinSize(Size size)
{
if (size.Width < minWidth || size.Height < minHeight)
{
if (size.Width < minWidth) size.Width = minWidth + 10;
if (size.Height < minHeight) size.Height = minHeight + 10;
return ApplicationView.GetForCurrentView().TryResizeView(size);
}
return false;
}

Transform Screen.PrimaryScreen.WorkingArea to WPF dimensions at higher DPI settings

I have the following function in my WPF application that I use to resize a window to the primary screen's working area (the whole screen minus the taskbar):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
int theHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
int theWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.MaxHeight = theHeight;
this.MinHeight = theHeight;
this.MaxWidth = theWidth;
this.MinWidth = theWidth;
this.Height = theHeight;
this.Width = theWidth;
this.Top = 0;
this.Left = 0;
}
This works very well, as long as the machine's DPI is set at 100%. However, if they have the DPI set higher, then this doesn't work, and the window spills off the screen. I realize that this is because WPF pixels aren't the same as "real" screen pixels, and because I'm using a WinForms property to get the screen dimensions.
I don't know of an WPF equivalent to Screen.PrimaryScreen.WorkingArea. Is there something I can use for this that would work regardless of DPI setting?
If not, then I guess I need to some sort of scaling, but I'm not sure how to determine how much to scale by.
How can I modify my function to account for different DPI settings?
By the way, in case you're wondering why I need to use this function instead of just maximizing the window, it's because it's a borderless window (WindowStyle="None"), and if you maximize this type of window, it covers the taskbar.
You get the transformed work area size from the SystemParameters.WorkArea property:
Top = 0;
Left = 0;
Width = System.Windows.SystemParameters.WorkArea.Width;
Height = System.Windows.SystemParameters.WorkArea.Height;
In WPF, you can use the SystemParameters.PrimaryScreenWidth and SystemParameters.PrimaryScreenHeight properties to find out the primary screen dimensions:
double width = SystemParameters.PrimaryScreenWidth;
double height = SystemParameters.PrimaryScreenHeight;
If you wanna get the dimensions of both Screens you simply can use:
var primaryScreen =
System.Windows.Forms
.Screen
.AllScreens
.Where(s => s.Primary)
.FirstOrDefault();
var secondaryScreen =
System.Windows.Forms
.Screen
.AllScreens
.Where(s => !s.Primary)
.FirstOrDefault();
After this you can reach Width, Height etc. by using
primaryScreen.Bounds.Width
So Long ;)

c# winform screen resolution

I have a C# WinForms application and when I give the executable to different users the application displays in different sizes (based on their screen resolution). Some of the parts of the application can't be seen.
how can I set absolute 1280X800 for my forms and make sure that the form size will not be changed whatever resolution is!
You can use Control.ScaleControl and Control.Scale
private void MainForm_Load( object sender, EventArgs e )
{
float width_ratio = (Screen.PrimaryScreen.Bounds.Width / 1280);
float heigh_ratio = (Screen.PrimaryScreen.Bounds.Height / 800f);
SizeF scale = new SizeF(width_ratio, heigh_ratio);
this.Scale(scale);
//And for font size
foreach (Control control in this.Controls)
{
control.Font = new Font("Microsoft Sans Serif", c.Font.SizeInPoints * heigh_ratio * width_ratio);
}
}
Hope this helps.
Use the MaximumSize property of the form.
form.MaximumSize = new Size(1280, 800);
You can also set a MinimumSize if you don't want the user to make it smaller than a desired size.
You can instead design the GUI so it scrolls up and down more easily.You can make use of the following
Layout Managers
Docking
Anchors
The property
Screen.PrimaryScreen.WorkingArea
is very useful for form sizing and positioning. For example this code:
this.Width = Screen.PrimaryScreen.WorkingArea.Width/2;
this.Height = Screen.PrimaryScreen.WorkingArea.Height/2;
this.Top = (Screen.PrimaryScreen.WorkingArea.Top + Screen.PrimaryScreen.WorkingArea.Height)/4;
this.Left = (Screen.PrimaryScreen.WorkingArea.Left + Screen.PrimaryScreen.WorkingArea.Width)/4;
will place the form in which it is executed in the middle of the screen and size it to half the screen.
The WorkingArea var is used to exclude stuff like the task bar and other docked items on the desktop when calculating the size of the screen.
Hope this helps.

How to auto resize and adjust Form controls with change in resolution

I have noticed that some applications change their controls' positions to fit themselves as much as possible in the current resolution. For example, if the window is maximized, the controls are set in such a way that the overall GUI looks balanced.
Is it possible to make or implement this functionality in Visual studio 2010 using C#?
Use Dock and Anchor properties. Here is a good article. Note that these will handle changes when maximizing/minimizing. That is a little different that if the screen resolution changes, but it will be along the same idea.
Use combinations of these to get the desired result:
Set Anchor property to None, the controls will not be resized, they only shift their position.
Set Anchor property to Top+Bottom+Left+Right, the controls will be resized but they don't change their position.
Set the Minimum Size of the form to a proper value.
Set Dock property.
Use Form Resize event to change whatever you want
I don't know how font size (label, textbox, combobox, etc.) will be affected in (1) - (4), but it can be controlled in (5).
float widthRatio = Screen.PrimaryScreen.Bounds.Width / 1280;
float heightRatio = Screen.PrimaryScreen.Bounds.Height / 800f;
SizeF scale = new SizeF(widthRatio, heightRatio);
this.Scale(scale);
foreach (Control control in this.Controls)
{
control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
..and to detect a change in resolution to handle it (once you're using Docking and Anchoring like SwDevMan81 suggested) use the SystemEvents.DisplaySettingsChanged event in Microsoft.Win32.
sorry I saw the question late,
Here is an easy programmatically solution that works well on me,
Create those global variables:
float firstWidth;
float firstHeight;
after on load, fill those variables;
firstWidth = this.Size.Width;
firstHeight = this.Size.Height;
then select your form and put these code to your form's SizeChange event;
private void AnaMenu_SizeChanged(object sender, EventArgs e)
{
float size1 = this.Size.Width / firstWidth;
float size2 = this.Size.Height / firstHeight;
SizeF scale = new SizeF(size1, size2);
firstWidth = this.Size.Width;
firstHeight = this.Size.Height;
foreach (Control control in this.Controls)
{
control.Font = new Font(control.Font.FontFamily, control.Font.Size* ((size1+ size2)/2));
control.Scale(scale);
}
}
I hope this helps, it works perfect on my projects.
Here I like to use https://www.netresize.net/index.php?c=3a&id=11#buyopt. But it is paid version.
You also can get their source codes if you buy 1 Site License (Unlimited Developers).
How ever I am finding the nuget package solution.
add this code at page load do for all control or add all control in containers
int x;
Point pt = new Point();
x = Screen.PrimaryScreen.WorkingArea.Width - 1024;
x = x / 2;
pt.Y = groupBox1.Location.Y + 50;
pt.X = groupBox1.Location.X + x;
groupBox1.Location = pt;
in the form load event add this line
this.WindowState = FormWindowState.Maximized;
private void MainForm_Load( object sender, EventArgs e )
{
this.Size = Screen.PrimaryScreen.WorkingArea.Size
}
this.WindowState = FormWindowState.Maximized;

Categories