What's the advantage of device-independent pixels? - wpf

I'm learning about WPF. WPF uses device-independent pixels. But I can't really understand them. Why are they better than device-dependent pixels, if most other apps are device-dependent and WPF apps aren't? Would they stick out?

The advantage of device independent pixels is that when specifying a UI you can determine the size that UI components will appear on the user's device, regardless of the user's screen resolution. Unfortunately, it's not quite as simple as that, as it requires the user to have various settings set 'correctly', and it can be overridden by a user who wants to change the resolution of their device (e.g. a partially sighted user who wants to run at a low resolution to make text easier to read).
In addition to the other link posted, you can also check out this one:
Is WPF Really Resolution Independent?
Note that you can turn on snapping a control to device pixels with the SnapsToDevicePixels set to true to avoid the blurriness that occurs when a horizontal/vertical line is drawn on the boundary between two device pixels.

Before understanding device independent unit, it is required to understand what DPI is. DPI is dots per inch, that means there would be certain number (96 usually) of pixels in an inch . But what is important to understand is in Win32 environment this inch is not fixed in size as a physical inch. So when the number of dots increases / decreases by changing the resolution there would more / less number of dots in an inch as a result the "inch" size increases or decreases.
However in case of WPF the inch size is as good as a physical inch as a result every time the DPI changes the system adjusts it self accordingly.

It's about UI and font scaling depending on the system's DPI setting:
Not all applications are DPI-aware: some
use hardware pixels as the primary
unit of measurement; changing the
system DPI has no effect on these
applications. Many other applications
use DPI-aware units to describe font
sizes, but use pixels to describe
everything else. Making the DPI too
small or too large can cause layout
problems for these applications,
because the applications' text scales
with the system's DPI setting, but the
applications' UI does not. This
problem has been eliminated for
applications developed using WPF.
WPF supports automatic scaling by
using the device independent pixel as
its primary unit of measurement,
instead of hardware pixels; graphics
and text scale properly without any
extra work from the application
developer.
This is taken from the link Kishore provided. (http://msdn.microsoft.com/en-us/library/ms748373.aspx)

Related

Wpf Resolution Indepence and Native Resolution

WPF documentation and tutorials state that WPF is resolution independent which I understood shows a window in the same size in different resolutions (1600x1200 -> native and 1024x768) and/or DPI settings. However, when I tried a sample app. with different resolutions the sizes are different. On the net I found http://www.wpflearningexperience.com/?p=41, which use "native resolution" in order to see the same window size on different computers, however I could not understand the underlying concept.
Why native resolution for LCD is vital and resolution indepence is a term instead of DPI independence? Probably, I do not know/use terminology well, but I need a clarification in order to understand this issue.
I do not want to answer my own questions, but I think I got the point. Sorry for this premature question, but after a while I noticed the problem.
As far as I understand WPF uses System DPI (which you set by changing through Windows Desktop Settings) as a scale factor. For example in the tutorial above one of the computers have a native resolution of 1600x1200 and 96 DPI (94 actually as stated in the tutorial). Everything is fine because System DPI (96) is quite close to the real DPI (94) and WPF can use this information to scale your window.
As you know a Device Independent Unit is 1/96 inch and with the numbers above real pixel size (physical pixel on your screen) is multiplied with ( (1/96) * 96 ) which is equal to 1. So if you have a window with 300 DIU, then you will see ( 300/96 ) inch on your screen.
However, when you change your resolution without changing System DPI, here comes the problem which confused my mind. Say, you set the screen resolution to 1024x768 without changing the System DPI (still it is 96) and run the application again and you see a bigger window. This is the reqult of wrong System DPI and naturally wrong scale factor for WPF. WPF does not know much about your real DPI, it only uses the information you give to it which is System DPI. Let's recalculate our window size with this new settings. First we need scale factor which is ( (1/96) * 96 ) equal to 1. We can say that 1 logical pixel is also 1 physical pixel on screen. However, we changed the resolution and 300 pixel is not the same with the previous resolution. Previously we have 1600 pixel on the diagonal which is also 17 inch in length. However, we have 1024 pixel for 17 inch now. 300 pixel is almost 5 inch on our new resolution (1024x768), but only 3.18 inch in the previous resolution (1600x1200). Therefore, WPF cannot be resolution independent due to the wrong DPI value and draws a larger window with the new resolution.
So, how I fix the problem (in my words, I do not claim that this is an absolute solution)! When I change the resolution, I also changed the DPI value which is true for this new resolution. For example, for my own monitor the diagonal size is 17 inch with a resolution of 1024x768, I use the formula (1024 pixel / 17 inch) and find that my new true DPI is almost 60 DPI. I set the System DPI to 60 (through the Desktop Settings of course) and it works. Not perfectly, due to the rounding errors during the calculations, but in practice values can be considered equal.
WPF uses System DPI in order to be resolution independent and you need to set actual DPI (real DPI value for current resolution). You need to set DPI in order to help WPF to be resolution free. Finally (and I think very crucially) you have do one more thing, at least on Windows XP, you need a restart in order to enable your DPI settings with the new value. If you do not (as I did), WPF still make the calculations wrong and draw in different size.
These are my understanding and results from the tests I did, but I cannot claim they are absolute. I just want to share it with the people who may find this information useful. Please comment/edit my post if you find any error or think that needs improvement.

WPF font quality

I'm developing a WPF app but I've noticed that at certain font sizes the text doesn't render as nicely as the samples you see in Control Panel -> Fonts. I'm using large Segoe UI fonts (FontSize="36"), and the effect is more noticeable on the upright lines, e.g. a letter "U" might be slightly thicker on one side than the other.
).
The font quality improves at certain font sizes, e.g. FontSize="48" (which I believe is the equivalent of 36pt), but using a limited number of font sizes isn't always practical.
I can improve the font quality by applying the following properties to the TextBlock:-
TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="ClearType"
Given the improvement in quality I'm curious to know why WPF doesn't do this for all text, or is it down to performance? I was thinking of creating a global style to apply this to all controls, or will this cause a problem?
(I tried uploading a screenshot but SO must store images at a low quality, and you couldn't really make out the font problem).
Here is the blog post that the WPF Text team wrote about this feature.
Note for the TextFormattingMode:
Ideal Ideal text metrics are the metrics which have been used to
format text since the introduction of WPF. These metrics result in
glyphs’ shapes maintaining high fidelity with their outlines from the
font file. The glyphs’ final placement is not taken into account when
creating glyph bitmaps or positioning the glyphs relative to each
other.
Display In this new formatting mode, WPF uses GDI
compatible text metrics. This ensures that every glyph has a width of
multiple whole pixels and is positioned on whole pixels. The use of
GDI compatible text metrics also means that glyph sizes and line
breaking is similar to GDI based frameworks. That said, glyph sizes
are not the only input into the line breaking algorithm used by WPF.
Even though we use the same metrics as GDI, our line breaking will not
be exactly the same.
Since these properties are new in .NET 4.0, they kept the original WPF algorithm as default, which is Ideal mode.
For the TextRenderingMode
Auto This mode will use ClearType unless system settings have been
set to specifically disable ClearType on the machine.
Aliased No antialiasing will be used to draw text.
Grayscale Grayscale antialiasing will be used to draw
text.
ClearType ClearType antialising will be used to draw text.
Since Auto is default, you will generally get ClearType rendering.
Now, because these are attached properties, and they inherit, you can just set them at the root Window. No need to create a bunch of Styles.
I have noticed small performance issues when dealing with large amounts of data (upwards of 10,000 items) when ClearType is turned on. Changing TextFormattingMode to Display has no visible performance impact.
This said, in all of my WPF apps I use global styles to improve text rendering, unless the performance impact is large enough to make the UI feel sticky.

WPF & resolution independent

if i put everything in viewbox container then my wpf apps will be resolution independent or do i need to do anything else. please help with concept.
Scale elements accordingly to the available screen or medium size
If your desire is, to allways fill some room of the screen or output device, independently of the metrics, using the viewbox is a good choice. If you have a big monitor, you will have a big element, if you have a small paper, you will have a small print out of the same element.
With the Stretch-property of an image you have a similar possibility only for pictures.
Make elements on every device equaly sized
WPF is designed "resolution independent". The goal of this resolution indepency is, that if you design an element to be 15 inches, then it will be on every output medium this 15 inches, independently of the resolution of your output device. Calculaction and specification of dimensions is done in "device independent pixels" (DIP) which you can convert to centimeters or inches without having specific knowledge about the output devices resolution.
96DIP == 1inch == 2.54cm;
1 inch == 96DPI;
1 cm == 37.8DIP;
If want to use this resolution indepency, you can set fixed values (in DIPs) to your elements. On a large monitor then your element then maybe only uses a small part (e.G. 15inches), and on a small monitor it fills the whole screen (also 15inches).
WPF is resolution independent without any extra tricks at all. If you host legacy controls (non-WPF controls) then this may break for them, but WPF itself is resolutions independent and vector based.
Viewbox has nothing to do with resolution independence.
Resolution independence means, controls you specify can be drawn on different resolutions while keeping scale. So you can use display that has 10x bigger density of points, but controls will still look same to you.
And like it was said, WPF itself was designed with this in mind, you dont have to do anything.

What measurement units does Silverlight and WPF use?

Does anyone know what measurement units are used by Silverlight/WFP? For example, if I create a new button and set its height to 150, is that 150 pixels? points? millimeters?
I design all of my applications in Adobe Illustrator before proceeding to code, and although I try and set everything to the dimensions in my Illustrator file, the Silverlight application is usually larger.
Although in theory, 1 unit in WPF is 1/96th of an inch, that's frequently not the case in practice.
It's usually true when printing. But it's rarely true on screen. The reason for this is that Windows almost always knows the true resolution of a printer, but almost never knows the true resolution of a screen.
For example, I have three screens attached to my computer. Windows thinks that they all have a resolution of 96 pixels per inch. Actually they don't. Two of them have a resolution of 101 pixels per inch, and one has a resolution of 94 pixels per inch. (Why? Because Windows has no way of working the true resolutions out for itself, and I haven't told it. The fiction that they all have the same pixel size is close to the truth, and turns out to be a convenient fiction.)
So when I create, say, a Rectangle in WPF with Width and Height both set to 96, the size of the Rectangle actually depends on which screen it appears on. Windows thinks that all 3 screens have a resolution of 96 pixels per inch, and so it'll render the rectangle as being 96 pixels tall and wide no matter which screen it appears on. That'll make it appear 0.95 inches tall on two of the screens, and 1.02 inches tall on the third.
So in practice, that means that units in WPF on my computer here are either 1/100th of an inch, or 1/94th of an inch in practice. (I.e., in practice, the size of 1 unit in WPF is exactly the size of 1 pixel on my particular setup, no matter how big the pixels happen to be.)
I could change that. I could reconfigure Windows - I could tell it the actual resolution of all 3 screens, in which case the nominal and actual WPF unit sizes would coincide. Or I could lie - I could claim that I have 200 pixel per inch screens, in which case everything would be massive...
The basic problem here is that there is no standard way for the computer to discover the true size of the physical pixels on the screen, and very few people bother to set it up by hand. (And in fact you can cause problems by configuring it 'correctly', because a lot of software doesn't behave correctly when you do.) So the majority of Windows computers don't report physical pixel sizes correctly to WPF - they can't because they don't know.
Consequently, there's no reliable answer to the question - 1 unit in WPF could be pretty much anything on screen. (In practice, most of the time, it turns out to be 1 pixel, simply because if you don't tell Windows anything else, it defaults to assuming that your screens have pixels that are 1/96th of an inch tall, which is the same as 1 WPF unit. And for most desktop screens, that's actually quite likely to be a good guess. But this isn't universal. On systems configured with what used to be called 'large fonts' for example, you'll find a different nominal screen resolution, and 1 WPF unit will correspond to slightly more than 1 physical pixel - about 1.2 in fact.)
With printers, it's all much more predictable. Printers are invariably able to report their resolutions correctly. So if you print something that's 96 WPF units high, you can be confident that it will be 1 inch high.
MSDN's documentation states that the FrameworkElement.Height property (for Silverlight) refers to:
The height, in pixels, of the object
However, for WPF it refers to:
a device-independent unit (1/96th inch) measurement
So, to answer your question... pixels for Silverlight, device-independent units for WPF.
The documentation refers to Pixels, however these are Pixels where there are 96 such pixels per inch. A line of Width 96 when display on a 120 DPI display will be 120 actual device pixels. Similarly such a line drawn on a printer output which has 600 DPI will be 600 pixels long.
They are Device Independent Units.
You can find more detailed explanations here.

Silverlight 3: Techniques for adjusting to screen resolution

My developer's box has a screen resolution of 1680 x 1050. I'm developing a full-screen Silverlight 3 application that I'm considering deploying to the Internet. So, I want to make sure the application looks good on a variety of screen resolutions. I just started testing on other boxes, the first one having a screen resolution of 1024 x 768. During the test I found some of the pages on the application were partially truncated. It seems the controls on the page didn't adjust for the lower screen resolution. So, I'm looking for some tips on how to make a Silverlight application, to the extent possible, adjust for screen resolution. For example, are there things one should or should not do on XAML to make adapting to screen resolution easier? Should I just optimize for a minimum screen resolution? Your thoughts and suggestions are welcomed.
You can easily enforce a minimum acceptable resolution by setting the MinHeight and MinWidth properties of your root visual. (Of course, this should be less than the minimum screen resolution to account for browser chrome.)
Try to specify absolute Width and Height only when necessary: for example, for images or icons of fixed dimensions, or for obvious cases like TextBoxes (whose width should reflect the average length of the data entered).
Grid panels are excellent for mixing scalable and fixed layout areas. The star sizing specification takes a bit of getting used to--it's not as simple as a percentage-based proportioning--but it's much more flexible, especially in combination with row/column min/max dimensions.
You don't really need to test on multiple resolutions unless you're interested in testing a range of dots per inch--just resize the browser to approximate different screens. Since there's always a bit of give and take depending on the user's browser configuration, you'll have to account for some variance anyway.
You can make your application scale with the Silverlight Toolkit ViewBox or make it strech with layout controls like the Grid, StackPanel, and WrapPanel. Make your main UserControl have a Width and Height of Auto (or remove the width and height entirely) and the size of the app will resize to the size of the parent div (the default HTML template uses 100%x100%). Then just resize the browser accordingly. IE8 has developer tools that can help you see your app resized to specific screen resolutions.
Testing on a variety of screen resolutions is always a good idea.
I covered the resizing of elements and making it resolution independent on another thread.
You can have a look here, there are multiple ways to sizing and resizing things automatically.

Resources