UI Scaling/Settings - c#

I've been working on a UWP application that will initially be deployed only to Surface Pro 4 (Maybe some SP3s) devices but I'm having a real difficult time getting my UI to fit on the screen.
Right now my Designer window is set to '12" Tablet (2160 x 1440) 150% Scale' with it locked in landscape mode (the only way this app will be used) so that the 'Effective: 1440 x 960' resolution is set.
I've got my MainPage page set to 960 x 1440 with a Frame for display content essentially filling the entire 960 x 1440 but when I run the app (either in full screen or windowed) it cuts off the content of my MainPage (not just the frame content but part of my app sidebar menu).
That all being said my question(s): How do I get my UWP to scale my content to fit inside what ever size window the app is displayed in when running (full screen or user adjusted window size), OR what settings do I need/How do I configure it to display my entire MainPage contents on my SP4 screen (2736 x 1824) in fullscreen without just trial/error adjusting elements manually until they fit.
I'm more concerned with the second question because I don't just want this app to do what I want (because I know I can figure it out myself by manually sizing elements) but I want to understand why it's doing what it's doing and the right way to go about doing what I want to do.
I did a lot of searching but could not find the answer to my question, if this is a duplicate please feel free to link the answer.
Thanks in advance.

The Designer just gives you a general guide on how things would look. The demensions are not for SP4 specifically.
At 150% DPI, try setting your MainPage to 1824, 1216.
You can call
ApplicationView.GetForCurrentView().VisibleBounds
at runtime to find how many pixels(epx) that your screen is currently set to.
Note that these are effective pixels. They are different from the physical pixels of the device. All UWP UI measurements are epx based. So when you see this -
<Button Width="24" />
You should know that the value 24 is measured in epx.
To find out what epx really is, give this a read.

Related

Can I automatically scale a form for DPI without it getting blurry?

I am developing a WinForms application in C#. It uses a panel to draw an image of the Mandelbrot fractal. In the manual for the program and whenever I post about it somewhere, I recommend people to set their scaling setting to 100%, as otherwise the images won't look nice. This is because on other settings, the image is scaled up after drawing it, and it becomes blurry. All other controls are blurry too.
For example: my panel is 500x500. The scaling in my Windows is set to 125%. When I run the program, the panel is internally still 500x500, but it appears as 625x625, blurry. Instead, when the program is run, I want the panel to internally resize to 625x625, and appear as 625x625 too.
I have found the following solution: I found out about SetProcessDPIAware() (from here). Setting that makes the window not scale (it appears as if it was at the 100% scale setting), but the text does (and without becoming blurry). I can then, at the start of the program, calculate the appropriate multiplier (dpi = DpiX / 96) and give that to a huge method that includes commands like
xentrylabel.Location = new Point((int)(xentrylabel.Location.X * dpi),(int)(xentrylabel.Location.Y * dpi));
xentry.Location = new Point((int)(xentry.Location.X * dpi), (int)(xentry.Location.Y * dpi));
xentry.Size = new Size((int)(xentry.Width * dpi), (int)(xentry.Height * dpi));
One for every control property that might need to be updated. While writing this question, I got this idea and got started with it. However, I realised that this will need very many lines of code, so I wonder if there isn't a built-in way to do this. It seems like an option that many would like to go for, rather than their applications becoming blurry or hard to read on screens with high dpi.
Is this way of manually correcting positions and sizes the way to go, or is there a built-in way to scale the form for other DPI settings by actually scaling everything in the form, instead of scaling the end result?
Edit: From some comments it seems as if SetProcessDPIAware() alone should scale up everything. But in my experience, it doesn't. Here are some screenshots:
Application on 100% scale setting:
https://i.stack.imgur.com/pws9B.png
Application on 125% scale setting without SetProcessDPIAware():
https://i.stack.imgur.com/cE4Wx.png
Application on 125% scale setting with SetProcessDPIAware():
https://i.stack.imgur.com/oVA8W.png
We solved the issue of rendering controls for high DPI screens with scaling greater than 100% in Chem4Word by creating a WPF user control which is hosted in an ElementHost control, which is set to fill the form.
WinForm
+- ElementHost
+- WPFUserControl
Looking at your uploaded images, that's exactly the problem which is solved by using a WPF user control.

Form oversize than setting

My working laptop is 1920 x 1080. C# form size set to the 1920 x 1080 with Top most set as true, and window state set to maximum. A panel was sized to 1850 x 500. Here is the part that puzzled me, the form displayed during debugged was wider than the screen, the panel was wider and the left edge was not displayed.
This the first time I come across this. Any idea how to resolve this?
One more thing: the Screen.PrimaryScreen.Bounds value is 1536 x 864
why not 1920 x 1080 ?
Hans Passant is correct.
I checked my dell development notebook (window 10 home), the default and recommended "Change the size of text, apps, and other items:" was set at 125%.
I tried and test the same project files at another desktop ( which has a default setting at 100%).
voila : the normal display like WYSIWYG ! A hard lesson learned. I had to rework all the UI all over again.

How to align windows when they are very near

I have an application with some small windows on the screen. I would like to align them to each other, so when I move one close enough, it will automatically be align with the other. Helping me positioning and size them all.
How can I know the position of other windows when there isn't a parent window? Is it possible to know it even if they are different process (applications)?
I am not fully sure what you mean but the following trick is what I use for dynamic layout and it gives me full control over anything, you just need to play around with it and you can easily get the distance between two windows.
This code is copied from a windows phone app but it is easily understood.
width = Convert.ToInt32(Window.Current.Bounds.Width);//gets window width
height = Convert.ToInt32(Window.Current.Bounds.Height);// gets window height
double dist Math.Abs(Btn1.GetValue(Canvas.LeftProperty) - Btn2.GetValue(Canvas.LeftProperty) + Btn2.Width);
note first two lines are only in order to have the proportions right in every single movement and resize you do, you can keep it all proportional to the window size.

Unable to fix Screen Resolution for different devices like projector,monitor of asp.net projet

I am working on project in ASP.NET WEB APPLICATION in which I am having problem with screen Resolution. Whenever I connect my project execution to different devices like from laptop to monitor or to Projector, the fields, labels, drop down lists and other are randomly displaced on the screen. I want to have same display look irrespective of the device on which the out put is being seen. I have seen so many ways but I couldn't find the one which suits my scenario.I want to adjust the out put to be displayed in same way when the resolution is changed that is like from 1024*768 to 1280*1024, etc. I want the out put to be spread across the entire screen in same manner irrespective of the resolution.In the project the resolution for all the controls is declared in measure of pixels not on percentage based.I don't want to change pixels into percentage that makes me to change every where in the project but by keeping them as pixels I want to adjust the resolution whenever it is changed so that the controls will be evenly displaced. Please help me with this.
Set up a displacefactor, that displaces "objects" on x, and y axis by a value calculated from the resolution. I'd check if the "object" is on the left or the right side of the screen (by getting the width of the screen and if its bigger than the half then displacefactor is poisitive, if not then its negative, and you displace the object on the x axis), you can do that with the height so you can displace them on the y axis. I can't be more specific because i can't program C# nor javascript, but i hope you understand what i'm trying to explain.

notifyicon image looks terrible once image ends up in system tray

I am using Visual Studio 2010, C#, on Windows 7.
I have added a notify control to my project and set it to an icon I have imported to the project. The icon image is really good looking if I just preview it, but once I run my code and see it in the system tray, then it's really terrible, like the sides are dotted instead of straight lines and so on. I have tried 16x16, 24x24, 32x32 and 48x48 of the same file but I am having terrible results.
Have I missed anything?
myNotifyIcon.Icon = SysDir.Properties.Resources.icon2_32_ico_rgba;
The problem with directly using the icon in your resources is that instead of choosing the right icon version in you icon file, the framework simply scales the default icon version to whatever size the notification area needs. That's why you are seeing jagged edges.
To get the best quality, you'll need to choose the right size in your icon by yourself.
First, instead of directly setting your NotifyIcon.Icon to an icon in your resources, create a new Icon instance. Doing so will allow you to choose a specific icon size in your icon resource. Using SystemInformation.SmallIconSize will get you the size the notification area needs.
So :
myNotifyIcon.Icon = new Icon(Properties.Resources.MyIcon, SystemInformation.SmallIconSize);
Now, SystemInformation.SmallIconSize always returns the right icon size, but only if your application is DPI-aware (otherwise, it always returns 16). If your application isn't DPI-aware, and it is used on a system where DPI-scaling is enabled, the line above will select the 16x16 icon in your resource, at it'll be scaled up to whatever size the notification area needs (in other words, ugly icon).
By making your app DPI-aware, SystemInformation.SmallIconSize will return the right size, taking into account DPI-scaling. For instance, if DPI-scaling is at 150%, SystemInformation.SmallIconSize will return 24 (16 × 1.5).
To make your app DPI-aware, simply add this to your app.manifest, inside the <asmv1:assembly> tag:
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
Edit:
The info I am linking seems to be suspect at this point. Try it out, but if it isn't working, then I suggest you edit your question to post screenshots of all your experiments (each icon size and how it gets scaled).
Original:
32x32x256 is the right size and color depth according to this link:
http://www.hhhh.org/cloister/csharp/icons/
But you have to be very careful when constructing that image:
Take a 16x16x256 image, and get it to look nice
Double it to 32x32 (careful not to blur or resample if doing this in a paint program)
The reason is that Windows will "resize" the 32x32 image to 16x16 by simply throwing away 3/4 of the pixels. The link above demonstrates this phenomenon with a couple screenshots:
Before:
After:
I'm not sure how much of the color-depth pickyness (256 colors only?)/resampling issues are still true on Windows 7, but it certainly seems to be the case on XP.
I use NotifyIcon in a C# WinForms application and no matter what the icon I use contains, after 2 resolution changes it ends up blurry.
My best guess is, that windows doesn't actually rescale the original every time but rescales the (already rescaled) version from the icon cache.
The only solution I found so far was setting the icon again after a resolution/dpi change:
SystemEvents.DisplaySettingsChanged += (sender, eventArgs) => {
trayIcon.Icon = MyIcon;
};
I tried all kind of resolutions and bit depths in the icons but they all got blurred eventually. Now I only use a single 16x16 32b image in the icon and so far it works great on all tested displays.

Categories