Resolution Independent UI

Abhi2434
Posted by in WPF category on for Beginner level | Views : 23799 red flag
Rating: 3.33 out of 5  
 3 vote(s)

It is a common problem to fix resolution related issues. Here I will demonstrate, how your UI will fix itself automatically using few tricks.


 Download source code for Resolution Independent UI


Introduction

It is very important to keep track of Operating System Resolution while building one application. We do lots of things to make our application work the same way in various ranges of Operating System Resolutions. For WPF developers, it is quite obvious to miss out the Anchor and Dock properties, which is present in Windows Applications but quite annoyingly absent here. The result of this is, when we change the Resolution of the Display, the UI of the application gets waked up abruptly.

"Oh god, how can I solve the same problem once again" --- This is what I thought after I built a brand new application altogether tested it in various Resolutions that is supported in my machine, and saw that it just didn't worked in a machine of one of my colleague. Well, even I thought of changing the machine resolution to something that suits my application and revert it when application closes ( Just like what DirectX games does).

The idea was good, but this would slow down performance, and also make other programs running in the windows unusable. I was very worried for the last couple of days, until today, I found a way of eliminating the problem using ViewBox.

While development of UI, I always liked to avoid ViewBox, as ViewBox generally changes the normal behavior of the UI elements. But strangely enough, I found that is the only way to make the UI look the same in all other Resolution possible.




Using the ViewBox


ViewBox actually stretches or shrinks the User Interface totally based on the size it provided to. Inherited from Decorator, it actually stretch the control with the available space. Now there are few considerations that you need to keep in mind while using ViewBox. ViewBox actually stretches its control without considering the normal behavior as I said earlier. Thus if you have placed a ScrollViewer, you must make sure that it has its height / width specified correctly. If you dont, the whole content of the ScrollViewer will be stretched to the available space. If there is no space, it will shrink the contents of the ScrollViewer and show it within the specified area.

Another example, if you are using WrapPanel. Generally, a WrapPanel wraps the content after certain width is reached. But if placed within a ViewBox, it doesnt, it actually puts all the controls in a single line and shrinks itself.

In our case, you should take care of defining the height and width of each of the controls you specify, so that it doesnt goes with the default behavior of ViewBox control.

<viewbox stretch="Fill">
<grid width="600" Height="800">
</grid>
</viewbox>
There are few properties of ViewBox, which you might look into. One of the important property is Stretch. When Stretch is specified to Fill, it will fill the content exactly with the screen resolution.  You can also specify Uniform or UniformToFill based on your requirement, if you want the Ratio of resolution being intact.

Here in the above snippet, I added a grid with Width=600 Height=800, which means the actual size of the Grid is 800/600. But as HorizontalAlignment and VerticalAlignment of any control is Stretch, and there is nothing specified with ViewBox, so the ViewBox will stretch itself, and as a result the Grid will also stretch itself accordingly. Now, you can check the UI in different Resolution, and I bet, it will look the same way in all.

Therefore, the choice should be very accurate. Always think of building your application in a layout which most of your users will have. If you think  that your users will generally use 1024 x 768 rather than 1400 x 900, it is smart to build application in 1024 x 768. Its because, even though ViewBox zooms itself according to the size of the Resolution, it actually produces irregular edges, blur textual data etc.

How about SnapsToDevicePixel


WPF actually generates device independent pixels. Thus it does not depends on the actual device pixels. The pixels generally scales itself with the actual DPI settings when its being rendered. This might create blurry effect when the control edge goes in between the pixels. To fix this issue, you can choose the SnapToDevicePixel property to true for the entire Visual Tree to render the controls just using the actual device pixels and results in Transparent edges and anti - aliasing.

In case of building the application, you need to also use SnapToDevicePixel = true to enhance the UI look and feel. You need to consider a few important tips while declaring your controls and maintain the SnapToDevicePixel = true for the entire VisualTree.

  • While declaring your control, it is better to wrap the control around a Border and set the SnapToDevicePixel of it to true.
  • If you are building a Custom ControlTemplate for a control, and also using a ScrollViewer/ ItemPresenter/ ContentPresenter, put its SnapToDevicePixed bound to TemplatedParent using TemplateBinding.
Other than that, setting SnapToDevicePixel for any control will not visually change anything.

<ComboBox >
<ControlTemplate>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ControlTemplate>
</ComboBox>
In this sample code, you can see, for my ComboBox, I added a ContentPresenter, of course it will look odd, as I didn't defined the entire control, ,but it is just to show how we can use it in ContentPresenter.


Conclusion


It is always said not to use ViewBox for your application, as it might affect performance of your application. ViewBox is very resource hungry, so do not use it much. Design your layout avoiding the ViewBox. If it is possible for you, it is always better to design the application to work on every resolution. But for quick fix, ViewBox is the only option. I think using one ViewBox in a page, will not affect much.


Hoping this would help you in long run. Try out the sample application in different Resolutions and see if it works well or not. Also you can try putting UniformToFill or Uniform to the stretch and see how it differs when resolution Ratio changes.

Thank you for reading.

Page copy protected against web site content infringement by Copyscape

About the Author

Abhi2434
Full Name: Abhishek Sur
Member Level: Silver
Member Status: Member,Microsoft_MVP,MVP
Member Since: 12/2/2009 4:19:08 AM
Country: India
www.abhisheksur.com
http://www.abhisheksur.com
Working for last 2 and 1/2 years in .NET environment with profound knowledge on basics of most of the topics on it.

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)