ASP.NET 2.0: Implementing print stylesheets with themes

In ASP.NET 2.0, the recommended model for using stylesheets is to encapsulate them in a theme with relevant images and skins. To facilitate use of themes, webforms must contain a head tag with the runat=”server” attribute set: this ensures that any stylesheets included in the theme are referenced in the html head. As this is done automatically, you cannot control the media type in the html head where the css is referenced. Traditionally, I would have used two separate stylesheets and referenced them manually using the following code. You can still do this in asp.net, but this is not possible if you want to use the themes model:

<link rel="stylesheet" href="style.css" type="text/css" media="all" /> 
<link rel="stylesheet" href="print.css" type="text/css" media="print" />  

Fortunately, there is the less well known @media construct in css (which I only recently discovered). This wraps CSS elements so that they are only used for a specific media type. This allows you to add either print specific styles to your main style sheet, or have two separate stylesheets – one of which is wrapped using the @media construct. See example below:

@media print
{
   /* Print stylesheet overrides to go in here */
}

Note that as stylesheets behaviour defaults to media=”all”, stylesheet values are cumulative. This means that the print stylesheet must be included after the standard stylesheet, else standard stylesheet values will override the print stylesheet values. To solve this, the print stylesheet name should be alphabetically later than the main stylesheets name. Alternatively, the @media print block can just be placed at the bottom of the main stylesheet.

CSS: 100% Div height in Firefox and IE

To make a div fill the height of the browser in firefox and IE, all parent containers must also have 100% height (including the body container). Firefox differs slightly from IE, in that if the div is contained in a form (which is normally the case if developing an asp.net application), the form also needs to have 100% height. The following example demonstrates a simple centered layout with 100% browser height:
Note that the main content div has min height specified. This is so that the div background expands correctly in firefox etc if the content is higher than the browser height.

<html>
<head>
<title>Rob Nowik centered full height example layout</title>
  <style type="text/css">
    body, form
    {
        height: 100%;
        margin: 0;
        padding: 0;
        text-align: center;
    }
    div#mydiv
    {
        min-height: 100%;
        height: auto !important;
        height: 100%;
        width: 400px;
        margin: 0 auto;
        background-color: #BBB;
        text-align: left;
    }
  </style>
</head>
<body>
  <form action="blah.aspx">
    <div id="mydiv">Hello world</div>
  </form>
</body>
</html>

ASP.NET 2.0: Cross-page posting from a masterpage

I am currently in the process of writing a website in ASP.NET 2.0. On every page I want to show a search box, that directs the user to a search results page. I have done this by implementing a masterpage with a panel containing a textbox and search button that issues a cross page post (using the PostBackUrl property on the search button). Note that a panel was used so that a default action could be specified, i.e. so when the textbox was in focus and the user hit enter, the cross page post is made).
I could have implemented the search box using a html form (no asp.net controls) that posts to the search results page. I could have then interpreted the Request.Form collection. I decided, however, that I wanted to reference asp.net controls explicitly. This was done using the following code in the search results page (note the use of PreviousPage.Master.FindControl to get controls on the masterpage).

if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
    TextBox search = (TextBox)PreviousPage.Master.FindControl("TextBoxSearchBlog");
    string searchCriteria = Server.HtmlEncode(search.Text);
    Response.Write(searchCriteria);
}
else
{
    Response.Write("Not a cross page postback");
}

Note that to facilitate SearchResults.aspx correctly responding to posts from any page, I left out the PreviousPageType directive from the search results page, which would normally be in the following format: <%@ PreviousPageType VirtualPath=”~/Default.aspx” %>
Also note that PreviousPage is null if the search is submitted from the SearchResults page with the above code.