I've been writing a mobile application that needs to run on a variety of different number of Windows Mobile and CE devices over the past few days.
The Visual Studio forms designer provides nice tools to like docking and anchoring of controls so all looks good on devices of different resolution or when the screen is rotated.
One area that you still have to cope with manually is assigning the widths of columns in Datagrid's. If you forget this step, if you move from a 240x320 resolution PDA up to a 640x480 VGA device you end up with squashed columns. So take this example. If I run my application on the Windows Mobile 6.1 Professional Emulator (at 240x320) all looks well.
Now the same application, run on a VGA emulator (640x480) things all start to get squashed.
Of course you all know the reason for this. Different Windows Mobiles screen resolutions have different dots per inch (DPI).
To factor for these different DPI's we need to scale our columns appropriately for the current device type we are running on.
So the first thing we need todo is establish our current DPI. There's a nice easy way to get this information. I've wrapped this into a generic function as follows -
public static int DPI(Form frm)
{
SizeF currentScreen = frm.CurrentAutoScaleDimensions;
int dpi = (int) currentScreen.Width;
return dpi;
}
So no a VGA device we get a DPI of 192, on a 240x320 we get a return of 96. So far so good.
Now we need a nice easy way of scaling our columns to fit appropriately depending on our DPI value. I'm making the assumption at this stage that most commonly we work in the Visual Studio designer on a form of 240x320 aka 96 dpi. Anyway this is the scaling method I use -
public static int ResolutionScale(int scalevalue,int dpi)
{
if (dpi!=96)
return Convert.ToInt32(scalevalue * (dpi / 96));
else
return scalevalue;
}
Almost there. Next step is to call our scaling function whenever we lay out our DataGrid. This is achieved as follows -
public static DataGridTableStyle GridStyle(int dpi)
{
DataGridTableStyle ts = new DataGridTableStyle();
ts.MappingName = "NameValuePairFormatted[]";
DataGridColumnStyle tempcol = new DataGridTextBoxColumn();
tempcol.MappingName = "NameLabel";
tempcol.HeaderText = "Name";
tempcol.Width = Core.ResolutionScale(112,dpi);
ts.GridColumnStyles.Add(tempcol);
tempcol = new DataGridTextBoxColumn();
tempcol.MappingName = "Value";
tempcol.HeaderText = "Value";
tempcol.Width = Core.ResolutionScale(116,dpi);
ts.GridColumnStyles.Add(tempcol);
return ts;
}
So putting it all together, this is what my grid display code looks like -
int dpi = Core.DPI(this); // get the current DPI
this.dataGrid1.TableStyles.Clear();
this.dataGrid1.TableStyles.Add(NameValuePairFormatted.GridStyle(dpi)); // lay out our columns
this.dataGrid1.DataSource = nvp; // bind and display our data
Final result on VGA device now looks like -
Thanks to Mike Holland who reminded me of this top tip.