You need to vary the look and feel of your application pages depending on the platform (Mac or Windows) that is being used.
Place an asp:Literal
control in the head section
of the .aspx
file, and then set the text
property of the control to an HTML style element created
programmatically in the code-behind. Use the properties of the
Request.Browser
object to determine the platform
type and control the generation of the style element.
In the .aspx
file, place an
asp:Literal
control in the head section.
In the code-behind class for the page, use the .NET language of your choice to:
Use the Platform
property of the
Request.Browser
object to obtain the
browser’s platform.
Check the platform string for the presence of the substring, such as “mac”, which indicates whether the browser is running on a Mac platform.
Based on the platform, programmatically create the HTML style element.
Set the Text
property of the
asp:Literal
control in the head section of the
.aspx
file to the created HTML style elements.
The .aspx
file used for this example is shown in
Example 18-13. The code-behind is shown in Example 18-14 (VB) and Example 18-15 (C#).
HTML is not always rendered the same. Different browsers and
different platforms render the HTML in a variety of ways. This
sometimes requires using a different stylesheet as a function of the
browser or platform the browser is running on (Windows, Mac, etc.) to
get the same visual effect. Refer to the Platform
property of the HttpBrowserCapabilities
class in
the MSDN Library for a complete list of platforms detected.
For instance, the displayed size of a font of a given point size is larger on the Windows platform than on the Mac platform. This is caused by the difference in screen resolution. The Mac platform uses a display resolution of 72 dots/inch (DPI), resulting in 1 point being equivalent to 1 pixel. The Windows platform uses a display resolution of 96 DPI, resulting in 1 point being equivalent to 11/3 pixels. To display a font the same size on both platforms, the point size must change as a function of the platform.
Our example programmatically generates a different stylesheet depending on whether the browser is running on a Windows or a Mac platform. It creates a stylesheet in the HTML that has four classes defined for a small, regular, large, and extra-large font. This technique is not new to ASP.NET, but the method of generating the stylesheet dynamically is much easier. Figure 18-3 shows the output of our example on a PC platform. Figure 18-4 shows the output on a Mac platform without generating a stylesheet specific to the Mac (the fonts are smaller than the ones in Figure 18-3). Figure 18-5 shows the output on a Mac platform using a specific stylesheet (the fonts are the same size as the ones in Figure 18-3).
Server controls can be placed almost anywhere in an
.aspx
file; they are not restricted to the body
section of the page. In our example, an
asp:Literal
control is placed in the head section
of the .aspx
file to provide a mechanism to
output a style sheet in the HTML sent to the browser:
<head>
<title>Dynamically Generating Stylesheet</title>
...
<asp:Literal id="litStylesheet" runat="server" />
</head>
Any control that returns data when a form is submitted must be within the open and close form elements.
In the Page_Load
method of the code-behind, the
platform the browser is running on is obtained from the
Platform
property of the
Request.Browser
object. The platform name is
converted to lowercase to simplify the check for the specific
platform.
The platform string is then checked for the presence of the substring
"mac
“, which indicates the browser is running on a
Mac platform.
After determining the platform, four variables are set to indicate the point size to use for the small, regular, large, and extra-large fonts.
A StringBuilder
is then used to create the HTML
style element. The style element includes a class for
smallFont
, regFont
,
largeFont
, and xLargeFont
. Each
class contains a font-family style along with a font-size style. The
font size is set using the variables described earlier.
Finally, the Text
property of the
asp:Literal
control placed in the head section of
the .aspx
file is set to the style element.
The resulting style element rendered in the HTML for the Windows platform is shown here:
<style type='text/css'> .smallFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:8pt
;} .regFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:10pt
;} .largeFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:14pt
;} .xLargeFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:18pt
;} </style>
The resulting style element rendered in HTML for the Mac platform is shown here:
<style type='text/css'> .smallFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:11pt
;} .regFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:13pt
;} .largeFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:19pt
;} .xLargeFont {font-family: Verdana, Arial, Helvetica, sans-serif;font-size:24pt
;} </style>
The classes in the stylesheet can then be used like any other class
that is hardcoded in the HTML or provided in a cascading style sheet
(css
).
<tr><td align="center" class="smallFont">
This is the small font. </td> </tr> <tr><td align="center" class="regFont">
This is the regular font. </td> </tr> <tr><td align="center" class="largeFont">
This is the large font. </td> </tr> <tr><td align="center" class="xLargeFont">
This is the extra large font. </td> </tr>
The solution provided in this recipe can be placed in a user control, giving you the ability to reuse the code in all pages of your application. Refer to Chapter 4 for examples of user controls.
An alternate solution to programmatically generating the stylesheet
would be to place a link
element in the head
section and then set the href
attribute to a
different pre-built cascading stylesheet as a function of the browser
and/or platform. This approach will yield better performance because
the stylesheet would not be built for each page request.
To implement the alternate solution, place the following link element
in the head section of the .aspx
file. Be sure
to add the /
at the end to close the element or an
exception will be thrown when ASP.NET parses the page.
<link id="linkCSS" runat="server" rel="stylesheet" />
Add the following protected reference to the
linkCSS
control in the code-behind. There is no
“Link” server control, so it must
be added as a generic HTML control.
Protected linkCSS As System.Web.UI.HtmlControls.HtmlGenericControl protected System.Web.UI.HtmlControls.HtmlGenericControl linkCSS;
In the Page_Load
method of the code-behind, add
the href
attribute to the
linkCSS
control setting the value to the required
cascading stylesheet. The href
attribute must be
added using the Add
method of the
Attributes
collection, because the generic HTML
server control does not have an href
property.
'check the users platform platform = Request.Browser.Platform.ToLower( ) 'set font sizes as a function of the platform If (platform.IndexOf("mac") > -1) Then 'platform is a Mac so add Mac CSSlinkCSS.Attributes.Add("href", _
"css/Mac.css")
Else 'since not a Mac, assume Windows and add Windows CSS '(production app may want to do additional checks if 'required for styles)linkCSS.Attributes.Add("href", _
"css/Windows.css")
End If // check the users platform platform = Request.Browser.Platform.ToLower( ); // set font sizes as a function of the platform if (platform.IndexOf("mac") > -1) { // platform is a Mac so add Mac CSSlinkCSS.Attributes.Add("href",
"css/Mac.css");
} else { // since not a Mac, assume Windows and add Windows CSS // (production app may want to do additional checks if // required for styles)linkCSS.Attributes.Add("href",
"css/Windows.css");
}
The resulting link
element for the Windows
platform is shown next. Note that an href
attribute has been added to the rendered HTML, with the value set to
the required cascading stylesheet:
<link id="linkCSS" rel="stylesheet" href="Windows.css"
></link>
The code for this alternate example can be placed in a user control to provide easy reuse in all of the pages in your application. Refer to Chapter 4 for examples of user controls.
Chapter 4 for user control examples; MSDN
Library for more information on the
HttpBrowserCapabilities
class and
Platform
property values
Example 18-13. Dynamically generated stylesheet (.aspx)
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH18DynamicallyGeneratingStyleSheetVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH18DynamicallyGeneratingStyleSheetVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Dynamically Generating Stylesheet</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"><asp:Literal id="litStylesheet" runat="server" />
</head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmDynamicStylesheet" method="post" runat="server" > <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Dynamically Generating A Stylesheet (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr><td align="center" class="smallFont">
This is the small font.
</td>
</tr> <tr><td align="center" class="regFont">
This is the regular font.
</td>
</tr> <tr><td align="center" class="largeFont">
This is the large font.
</td>
</tr> <tr><td align="center" class="xLargeFont">
This is the extra large font.
</td>
</tr> </table> </form> </body> </html>
Example 18-14. Dynamically generated stylesheet code-behind (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH18DynamicallyGeneratingStyleSheetVB.aspx.vb ' ' Description: This module provides the code behind for the ' CH18DynamicallyGeneratingStyleSheetVB.aspx page ' '***************************************************************************** Imports System Imports System.Text Namespace ASPNetCookbook.VBExamples Public Class CH18DynamicallyGeneratingStyleSheetVB Inherits System.Web.UI.Page 'controls on the form Protected litStylesheet As System.Web.UI.WebControls.Literal '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '-------------------------------------------------------------------------Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Const FONT_FAMILY As String = _
"font-family: Verdana, Arial, Helvetica, sans-serif;"
Dim platform As String
Dim smFontSize As String
Dim regFontSize As String
Dim largeFontSize As String
Dim xLargeFontSize As String
Dim styleTag As StringBuilder
'check the users platform
platform = Request.Browser.Platform.ToLower( )
'set font sizes as a function of the platform
If (platform.IndexOf("mac") > -1) Then
'platform is a Mac
smFontSize = "11"
regFontSize = "13"
largeFontSize = "19"
xLargeFontSize = "24"
Else
'since not a Mac, assume Windows (production app may want to
'do additional checks if required for styles)
smFontSize = "8"
regFontSize = "10"
largeFontSize = "14"
xLargeFontSize = "18"
End If
'create style tag
styleTag = New StringBuilder("<style type='text/css'>" & _
Environment.NewLine)
'output the smallFont class
styleTag.Append(".smallFont {" & FONT_FAMILY & _
" font-size:" & smFontSize & "pt;}" & _
Environment.NewLine)
'output the regFont class
styleTag.Append(".regFont {" & FONT_FAMILY & _
" font-size:" & regFontSize & "pt;}" & _
Environment.NewLine)
'output the largeFont class
styleTag.Append(".largeFont {" & FONT_FAMILY & _
" font-size:" & largeFontSize & "pt;}" & _
Environment.NewLine)
'output the xLargeFont class
styleTag.Append(".xLargeFont {" & FONT_FAMILY & _
" font-size:" & xLargeFontSize & "pt;}" & _
Environment.NewLine)
'close the style tag
styleTag.Append("</style>" & Environment.NewLine)
'set literal in Head section to output style sheet
litStylesheet.Text = styleTag.ToString( )
End Sub 'Page_Load
End Class 'CH18DynamicallyGeneratingStyleSheetVB End Namespace
Example 18-15. Dynamically generated stylesheet code-behind (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH18DynamicallyGeneratingStyleSheetCS.aspx.cs // // Description: This module provides the code behind for the // CH18DynamicallyGeneratingStyleSheetCS.aspx page // //**************************************************************************** using System; using System.Text; namespace ASPNetCookbook.CSExamples { public class CH18DynamicallyGeneratingStyleSheetCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.WebControls.Literal litStylesheet; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------private void Page_Load(object sender, System.EventArgs e)
{
const string FONT_FAMILY =
"font-family: Verdana, Arial, Helvetica, sans-serif;";
string platform = null;
string smFontSize = null;
string regFontSize = null;
string largeFontSize = null;
string xLargeFontSize = null;
StringBuilder styleTag = null;
// check the users platform
platform = Request.Browser.Platform.ToLower( );
// set font sizes as a function of the platform
if (platform.IndexOf("mac") > -1)
{
// platform is a Mac
smFontSize = "11";
regFontSize = "13";
largeFontSize = "19";
xLargeFontSize = "24";
}
else
{
// since not a Mac, assume Windows (production app may want to
// do additional checks if required for styles)
smFontSize = "8";
regFontSize = "10";
largeFontSize = "14";
xLargeFontSize = "18";
}
// create style tag
styleTag = new StringBuilder("<style type='text/css'>" +
Environment.NewLine);
// output the smallFont class
styleTag.Append(".smallFont {" + FONT_FAMILY +
" font-size:" + smFontSize + "pt;}" +
Environment.NewLine);
// output the regFont class
styleTag.Append(".regFont {" + FONT_FAMILY +
" font-size:" + regFontSize + "pt;}" +
Environment.NewLine);
// output the largeFont class
styleTag.Append(".largeFont {" + FONT_FAMILY +
" font-size:" + largeFontSize + "pt;}" +
Environment.NewLine);
// output the xLargeFont class
styleTag.Append(".xLargeFont {" + FONT_FAMILY +
" font-size:" + xLargeFontSize + "pt;}" +
Environment.NewLine);
// close the style tag
styleTag.Append("</style>" + Environment.NewLine);
// set literal in Head section to output style sheet
litStylesheet.Text = styleTag.ToString( );
} // Page_Load
} // CH18DynamicallyGeneratingStyleSheetCS }