Do larger monitors slow down winforms applications? - c#

Will WinForms apps run slower on larger monitors(i.e. larger resolution) as opposed to smaller all else being equal? My gut says yes, as there's more real estate to paint, but I cannot find any information anywhere regarding the effects.
I ask because we have a WinForms application that generally runs on two 22 inch monitors, but we have a couple users who run it on two 30 inch monitors, and they always seem to have more lag in their GUI than anyone using the 22 inch monitors.

The issue isn't really the number of inches, its the number of pixels.
Drawing to a 800x600 screen is less work than drawing to a 1920x1080 screen (roughly 4x less work).
Still, most of that work is likely done by a graphics card, and won't affect CPU load all that much.

Having graphics cards from competing chip makers (one nVidia and one ATI) may cause slow downs.
The application in question might also be poorly painting and it's not as obvious when the window is smaller but when it's bigger on the bigger displays the poor painting code is a bigger hotspot. You could try using a profiler to see what's going on. Visual Studio has one built in now, or you could try DotTrace http://www.jetbrains.com/profiler/

For the build-in winform controls, the difference won't be that much. In general, the rendering of these controls is pretty fast on any resolution.
Check if you are using custom painted controls. In many cases the performance is poor if the paint method is not implemented well. For example if you draw pixels (nested loops for width and height) the performance will slow down dramatically with increasing resolutions.
Another trick for custom controls is to enable double buffering, it can speed up things a lot for heavy paint routines:
public partial class YourControl : Control
{
public YourControl()
{
InitializeComponent();
this.SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);
}

Related

Disabling windows 10 scaling for specific application

I am having issues with some applications (mainly dashboard) that some user uses windows display scaling to make their icons bigger but this cause huge problems in my software. I am looking for a way to disable completely the scaling on my application and leave the application scaled to the pixels of the display resolution instead.
I have found this thread but it is 8 years old and windows 10 didn't exist at the time and another user gave an answer but it doesn't work either.
A simple example of the behavior happen mostly on dashboards as there is a lot of controls and widget on these kind of screens and they are critical for thing like robot machinery controller.
One example dashboard window is in it's minimum possible size 1900 x 980 (could be 4-5 pixel smaller in both direction but we rounded up to get rounded positions XY values). This resolution is just shy of 1920 x 1080. It Cannot be smaller but you can make it larger if you have a bigger screen like 4K and all you gain is more date in treeviews, better display in the 3d Engine renderer etc.
So some users have small laptop screen such as 15 inches that have a maximum resolution of 1920 x 1080 resolution but they use 150% scaling so my screen minimum size become 2850 x 1470 in their screen which make the application bigger than the screen and goes outside the screen.
An another example if i use a Windows Surface Pro which have a 2736 x 1824 resolution which is about 80% bigger than 1920 x 1080 the window does indeed still take the original 1900 x 980 pixels on the screen which make it look quite small so if you full screen it you see much more information in all controls. But then if you change scaling to 150% the screen now take again 2850 x 1470 pixels on the screen which is fitting perfectly on the height but on the width i am short by 100 pixels, and 100 pixels that's enough to loose the right part of my screen and you either cannot see the left most part or the right most part of the screen.
I tried the 3 auto scaling mode : DPI, Font and None and it doesn't work at all. It still stretch the screen no matter what. Changing the font of the forms doesn't help either, i manage to make it once work for few labels directly in the form but anything inside group box fail to change or grow twice in size compare to the rest.
Important points :
Project are .net 4.5 and 4.6 but there is no problem compiling them in 4.7if i need to for specific features.
WPF is out of the question. We took 3 years to implement it and ended up quickly with very bad performance with third party DLL and 3D Cad performance were simply abysmal.
Screens are already optimized with the least amount of controls possible. out of the couple hundreds of screen and thousands of user controls about half of them are very close to the limit of 1920 x 1080 which is around 90% of our clients
I have received a suggestion of running a Virtual Machine on the client computer with 100% scaling which is not affected by the host computer. It is probably my last resort as it's very difficult to handle dedicated video card through VM especially CAD card such as Quadro and FireGL.
Half the users use touch screen and we tried putting everything in a panel with 2 scrollbar and god it's awful and works once in a blue moon. So it's only good for mouse users and these users all have desktop AFAIK so 99% of them doesn't use scaling so they don't have the issue.
So is there anything nowadays that can fix or work around this issue ?
Did you try making your Process DPI aware?
You can either do it through a pinvoke:
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
and call
SetProcessDPIAware();
in your Main or create a Manifest and add
<dpiAware>true</dpiAware>
There is a tutorial here.
Declearing it DPIAware should stop windows from scaling by its own.

Trying to figure out how to match aspect ratio on mac to android

I'm making a shape matching game for toddlers.
I drew the shapes using gimp on my mac.
The images all seemed stretched out on the android devices.
Is there some mathematical way i could figure out how much shorter I have to make the images on the mac computer so they look correctly on the android devices?
This is a tough question. I have made several Apps for iOS and have pretty much the same problem with graphics for buttons and backgrounds when going between iPhone and iPad, which have different aspect ratios (which I suspect is the problem you are having). Throw orientation into the mix as well.
I use Gimp, Inkscape, Spine, Cocos2d-x, and lots of other tools for reference (see here).
As far as I know, the general options for "different screen geometry" issues are (if there are others, let me know):
Different graphics for each geometry.
Scaling the graphics proportionally for the geometry (I suspect you have this).
Same graphics for all, scale proportionally based on one dimension and then place graphics on screen using percentages for fixed stuff.
Option 1 means extra work...not acceptable for a hobbyist or indie (like me) developer.
Option 2 usually looks like junk. Frustration and sadness usually ensue.
Option 3 is the option I use most often. I find that occasionally I have to add small changes (read: hacks) based on the device or geometry. In the case of iOS, it is not too bad, because there are only two geometries to deal with. In the case of Android, where there are lots of different tablet geometries, you could cut it down by working with ranges of geometries and picking a fixed orientation for your application.
At the end of the day, proportional scaling by a single dimension (height or width) has gotten me the most bang for the buck.
I usually make the graphics a little "bigger" than I will need so I only have to scale down. This consumes a bit more memory, but I re-use a lot, use sprite sheets, etc. There is a definite tradeoff with managing every bit of memory (which you have to do in a large AAA rated game) and what you can get away with in a small independent application. I am not encouraging sloppiness or memory mismanagement; I'm encouraging balancing the resources against the developmental needs of simplicity...making the same graphics for different situations burns a lot of daylight.
ONE MORE NOTE:
For applications where I use a framework for the graphics (i.e. games), I use a "viewport" to let me match up the physics with the graphics...that is to say, dynamically scale the size of the graphics based on how much of the total scene I want the user to see. This lets me put the graphic for the "body" on top of it and match up the size statically or dynamically as needed. The code is in C++ and is only loosely tied to the framework...and the concept is applicable to general situations for games (i.e. scaling the graphics as needed). You can find some description and code here, if you are interested.
Was this helpful?
You need to design your application so that it can function correctly regardless of device resolution as many mobile devices have many different aspect ratios and resolutions.
If your images are being stretched then you need to change the ui design so that they are enlarged and spaced out to make use of whatever space there is.

C# PictureBox control flickering / performance issues

I am currently working in Windows Form Apps and am making what will essentially be a map editor for a game. The way i have gone about this is by having a central TabControl where each TabPage contains a custom PictureBox control and all the other UI controls are around this central TabControl. The PictureBox uses its Paint event to draw everything that is placed on the map, and therefore draws multiple images of many sizes, rotations and scales etc to the single PictureBox. This has all gone well so far. The TabPage is essentially used as a view window for the PictureBox and is of size (1280x720).
The problem is with the scale to which the maps are being produced. The avg (and also maximum) map size on screen is around 19200x10800px and can be made up of hundreds of items at any one point. When drawing just a backdrop image of size 19200x10800px the PictureBox starts to flicker when it redraws and makes the program unusable. As the map is so big you are able to pan around them and this is where the flickering really shows. Also i do not want to use a 19200x10800px image source if possible for the sake of file sizes and the scaled image quality isn't an issue at all.
I have done heaps of reading on why this might be and feel like I have tried everything up until this point. So far ive tried:
Having the background image only 1920x1080 and scaling it up by 10x
Starting with a 1920x1080 image, programatically resizing it and drawing this image
Slicing the background into multiple segments (i tried many different amounts) and drawing only the ones that the view window can see (tried this for both a small(1080p) and large(10800p) images)
Using graphics clipping so that only the things on screen would be drawn
Used Double Buffering on both the picturebox and the form that the picturebox is on
Converting the image at initialisation to an "optimised bitmap" with faster formatting and then drawing the bitmap
I've probably tried a couple other things along with minor optimisations but its taken me so long ive forgotten the rest. From what i've read its most likely something to do with the control redrawing too slowly for some sort of performance reason or a limitation with picturebox's, however exactly what is going on i cannot tell due to lack of experience with form apps controls.
Currently to draw the background in the Paint event i have either:
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width * levelScale), (int)(image.Size.Height * levelScale)));
or
g.ScaleTransform(levelScale, levelScale);
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width), (int)(image.Size.Height)));
Where g is the Graphics object.
Have I hit the limit of Win form apps capabilities or is there something i may be missing?
Any and all help appreciated,
Thanks in advance.
Just for formality I though id answer my own question just in case anyone else would like to know the outcome.
Based off the overwhelming consensus that winforms was just not made to do the things I was trying to do with it I decided I had to move to some other platform. Suggested to me was WPF, DirectX and OpenGL but after some extensive searching around I found what I think is the optimal solution.
In order to utilise the power of DirectX hardware acceleration MS has made it so that you can embed XNA graphics devices into a winforms application. Essentially you can create custom controls that run in the normal winform style that have access to a much higher caliber of graphics control. In this manner (with a bit of extra work) I have replaced the picturebox I was using with a custom graphics control which handles all of the drawing. This has worked very well, and on the up side i havent had to take too much of a hit to my development time.
For those looking for more info refer to this question which has further links that should help. Once again thanks to all those who gave their advice!
This is a quoted answer from the URL at the bottom. There are code examples at the link at the bottom. Hope this is helpful; not sure if you tried this yet and maybe it'll help you get a little more juice out of the existing picturebox control. As explain in the other answers, it sounds like you will be forced to a more powerful solution in the near future regardless (DirectX/OpenGL or WPF)
** Partial quote from http://social.msdn.microsoft.com/Forums/en-US/68ecd1f6-2eeb-45ce-a881-24c62145ab0e/c-picturebox-problems
"I'd guess the real problem is that it takes too long to redraw the images. GDI+ is pretty slow, it doesn't use any video hardware acceleration. To speed it up, be sure to avoid rescaling the drawing and to use the Format32PArgb format. It is about 10 times faster than any other format. Load the images into a Bitmap with the right format first."
If you have a LOT of items (Maybe realized as controls), forget about the standard event mechanism of Windows Forms. Some time ago, i've written a logic gate editor/simulator which supported lots of thousands of gates in the editor and was really fast. There, I've used the canvas and draw the gates as custom "images" instead of putting them as controls. You'll have to write a custom GetUnderlyingGate function which resolves the current gate / tile (Is your editor a tilemap editor?) from a coordinate array. Also, there were some visible area optimizations.
Maybe, when i'm back home, I'll upload some sourcecode and notify you.

C# custom control redraw slow

I have a C# Forms program with about 200 controls total. Some are within user controls which I have added to the Form. When I ran my program on my home machine, a Dual core AMD X64, 2.0Ghz with an ATI X1600 card, the program runs fine. It's fast and redraw is not a problem.
When I put this program onto my desktop, a quad core Intel 2.4Ghz, 4GB RAM, and a NVidia Gefore 8800GT, it slowed to a crawl when redrawing. Could this be a driver issue?
I have Double buffering enabled for all of my user controls and forms. No help there.
I have read this thread, but my situation is not the same:
Super slow C# custom control
the thing is ".SuspendLayout();" is not really stop drawing. i can't remember the statement but i believe u can get it on google.
and try to using .AddRange might help.
It's important to note that drawing controls is like painting on a 2D surface, overlapping as required. If the control does not understand things like rectangle clipping, it could be drawing a portion of the control that is not visible (especially controls that are hidden in another container, like a TabPage), wasting valuable CPU cycles. Additionally, controls that have their BackColor as transparent will attempt to mimic transparency by adopting the BackColor of its parent control. Since all of this occurs on GDI+, which is not hardware accelerated, having many controls that exhibit this behavior will exacerbate the slow down.

How to draw in C#/WinForms with decent speed?

I'm trying to visualise a graph and allow people to play with it. I found the excellent Graph# library that can create an initial layout so that part is covered. Now I need to make a control that actually draws it and provides the necessary interactivity.
Graph# comes with a nice visualiser itself, however I don't like it because it is written in WPF (while my app is WinForms), and because I want to add some more interactivity options, which would require quite a remake of it anyway.
The graphs I'm drawing will routinely be pretty large, at about 100 vertices and the same amount of edges (the graphs will be trees 99% of time). That means that the resulting rendering can be up to 2000px by 2000px and even more. The users should be able to zoom in and out, scroll, highlight and drag vertices and edges, and get some popups with additional info when hovering the cursor above a vertex.
I'm worried that the standard System.Drawing might not be able to deliver a decent speed for this. I would like the dragging/zooming/scrolling operations to be smooth, and the popups should open with a little animation as well. Something like 20fps should be a necessity.
I know I can try to speed things up by pre-rendering a lot of the elements and keeping them as bitmaps in memory - but that would probably take up lots of RAM, and I'm still not sure if it would deliver the necessary performance.
What are your thoughts?
"Premature optimization is the root of all evil"
GDI+ can be great for your needs. Don't go and buy 3rd party libraries before you know you even need them.
I've done a thousand polygons on a 1000x800 pixel bitmap and redrawn it completely at over 100 frames per second, using just GDI+
That being said, if you have a lot of drawing to do, and your resolution is big.. Some of the 3rd party drawing libraries can go WAY beyond what managed GDI is capable of.
I recommend leaving Graph# alone, and just hosting it in your Windows Forms application.
The performance you will receive will be much better than trying to reimplement it in System.Drawing.
GDI+ will be plenty fast enough for what you're doing, especially if (as it sounds from your description) everything you're drawing is rectangles and vertical/horizontal lines. Polygons and non-linear shapes are a bit slower, but not much (the speed difference is partially dependent on the SmoothingMode of your Graphics object). Drawing cached Bitmaps with resizing is also quite fast, although it can slow down significantly if you use a high-quality InterpolationMode setting.
As a benchmark, I wrote a .Net Compact Framework GPS application for Windows Mobile that rendered about 10,000 lines on the screen in realtime. This only achieved a frame rate of a few frames per second, but the processing power on a Smartphone is, of course, way less than a modern PC.

Categories

Resources