views:

3897

answers:

3

Hello,

I am developing a map control in WPF with C#. I am using a canvas control e.g. 400 x 200 which is assigned a map area of e.g. 2,000m x 1,000m.

The scale of the map would be: canvas_size_in_meters / real_size_in_meters.

I want to find the canvas_size_in_meters.

The canvas.ActualWidth gives the Width in DIU's (Device Independant Units). So, 400 DIU's is 400/96 = 4,17 inches, PROVIDED that the physical resolution of my monitor is 96 dpi.

However, using a ruler, I found that the physical resolution of my monitor is 87 dpi. (There are only few monitors that ACTUALLY have 96 physical dpi)

That DPI difference (10%) translates to a +10% difference in the actual map control width on screen.

How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?

+2  A: 

How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?

This isn't actually possible, because for it to work, WPF would have to know the resolution (in terms of DPI) of your monitor. Sounds nice in theory, but in practice windows doesn't know this information. This is why windows itself always assumes 96dpi blindly instead of being smarter about it.

Even if there were some way to manually tell it, or if your particular monitor has a custom driver that does pass the correct information to windows, this isn't going to work on anyone else's computer, so windows doesn't pass this information on to any applications.

The best you can do is draw a scale like google maps does. You know that 1 pixel == 1 mile, so you can draw a 50 pixel line on your map, with a label saying "this line equals 50 miles"

Orion Edwards
A: 

Thank you for you prompt reply.

I totally agree, but I didn't want to believe it in the first place. You see, there has to be an approximate calculation of the scale of the map if the map is used to display different layers of map data (scale dependant). Most applications use a slider control with e.g. 10 discrete map levels to set the "scale".

Having an absolute scale is not crucial for the application, it would be nice to display an indicative scale, like 1:15,000.

An absolute scale would require for an extra variable monitorPhysicalDPI (initially set to 96) that if the uses chooses to change would give slightly better scaling (again it's not crucial). The size of the map control would be:

map.ActualWidth * (96/monitorPhysicalDPI) * inchesPerDIU, inchesPerDIU is 1/96

Again these are cosmetics.. Wouldn't it be nice if Windows knew the ACTUAL control's dimensions? (user would have to give information about the screen dimensions on OS setup, or simply installing the monitor INF file)

It'd be great. You could view word documents and PDF's and set them to 100% zoom and actually view the correct page size. I'm stunned they haven't tried to fix this years ago :-(
Orion Edwards
A: 

There is way to compute current pixel size in mm or inches. As mentioned in the earlier posts, it is not a fixed value and would vary depending on the current resolution and monitor size.

First get the current resolution. Assume it is 1280x1024 Now get the monitor width in mm using GetDeviceCaps function. Its a standard windows library function.

int widthmm = GetDeviceCaps(deviceContext, HORZSIZE); My monitor width is 362mm

So pixel size = 362/1280 = 0.282 mm

The accuracy of this method depends on the assumption that the display area covers the width of the monitor exactly.

So to answer the original question, the canvas size of 400 x 200 pixels would be (400 * 0.282/1000) x (200 * 0.282/1000) in meters when shown on my monitor.