Permanently Redirecting a Page in ASP.NET 4

Rather that using Response.Redirect("newpage.aspx"), ASP.NET 4 introduces the RedirectPermanent method.

To signal that the redirect is of a permanent nature (such as a url to a page changing permanently) you can now call:

Response.RedirectPermanent("newpage.aspx");

This will issue a http response HTTP 301 (Moved Permanently) rather than the normal HTTP 302 (Found). This can potentially remove a round trip to the server.

From msdn.com: "Search engines and other user agents that recognize permanent redirects will store the new URL that is associated with the content, which eliminates the unnecessary round trip made by the browser for temporary redirects."

SHARE:

Hosting HTML Content in Silverlight 4

In Silverlight 4 we can present HTML content to the user.

The WebBrowser Control

For example to display the content of DontCodeTired.com we can set the Source property in XAML:

<WebBrowser Name="webBrowser" Source="http://www.dontcodetired.com" />

Or we can use the Navigate method of WebBrowser:

webBrowser.Navigate(new Uri(@"http://www.dontcodetired.com"));

The user can navigate to links, right-click and open in new tab (which opens up tab in a full web browser), view source, etc.

To use the WebBrowser the Silverlight app must be running out of browser (OOB), if you view when embedded in a web page (i.e. not OOB) the control displays a message saying that it can only be used in Out-of-Browser mode.

WebBrowser control running in-browser

WebBrowserBrush

Using the new WebBrowserBrush (previously HtmlBrush in beta 4) we can use the contents of a WebBrowser to fill another element.

For example, to fill an Ellipse with the content of a WebBrowser named "webBrowser" we define a WebBrowserBrush and sets its SourceName:

<Ellipse>
    <Ellipse.Fill>
        <WebBrowserBrush SourceName="webBrowser"  />
    </Ellipse.Fill>
</Ellipse>

The following example creates an ellipse which is filled with a blurred version of the content of a WebBrowser. One thing to note is that we hook into the WebBrowser's LoadCompleted event to ensure the ellipse is updated whenever a page has been loaded into the WebBrowser. When run it looks like the image below: 



XAML:

<UserControl x:Class="SL4HTMLHosting.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
       
        <WebBrowser Name="webBrowser"
                    Source="http://www.dontcodetired.com"
                    Grid.Row="0"
                    LoadCompleted="webBrowser_LoadCompleted">
        </WebBrowser>
       
        <Ellipse HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    Grid.Row="1">
            <Ellipse.Effect>
                <BlurEffect Radius="5" />
            </Ellipse.Effect>
            <Ellipse.Fill>
                <WebBrowserBrush x:Name="browserBrush"
                                    SourceName="webBrowser"  />
            </Ellipse.Fill>
        </Ellipse>
          
    </Grid>
</UserControl>

Code Behind:

using System.Windows.Controls;

namespace SL4HTMLHosting
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            browserBrush.Redraw();
        }
    }
}

Interacting With WebBrowser Content

The following example uses WebBrowser.NavigateToString which allows a string of HTML to be rendered rather than a page at some Uri. The example creates a simple html button which uses window.external.notify to pass a message to the WebBroswer control via it's ScriptNotify event.

XAML:

<Grid x:Name="LayoutRoot" Background="White">            
    <WebBrowser Name="webBrowser"
                ScriptNotify="webBrowser_ScriptNotify">                  
    </WebBrowser>          
</Grid>

Code Behind:

using System.Windows.Controls;
using System.Text;
using System.Windows;

namespace SL4HTMLHosting
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
           
            // Create some basic HTML on the fly containing a simple button,
            // that when clicked passes a message to the containing WebBrowser
            var html = new StringBuilder();
            html.Append("<html>");
            html.Append("   <body>");
            html.Append(@"       <input type=""button"" value=""Show Message Box"" onclick=""window.external.notify('button click');"" /> ");
            html.Append("   </body>");
            html.Append("</html>");

            webBrowser.NavigateToString(html.ToString());
        }



        private void webBrowser_ScriptNotify(object sender, NotifyEventArgs e)
        {
            MessageBox.Show(string.Format("Message from web page: '{0}'.",e.Value));
        }
    }
}
 

SHARE:

Introduction To jTemplates - A jQuery and JavaScript Template Engine

jTemplates is a great lightweight template engine for jQuery and JavaScript. It allows you to process data (e.g. JSON data returned from an AJAX call) and feed it ito a template definition rather than manually building your html elements.

jTemplates supports foreach, for, if..elseif..else constructs in additional to parameters, nested templates etc.

The example below defines a template to display a list of orders and for each order the list of items that belong to that order. It shows how nested foreach can be used. The project documentation goes into more detail.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
    <script src="js/jquery-jtemplates0.7.8.js" type="text/javascript"></script>
   
    <title>jTemplates Demo</title>
   
    <script type="text/javascript" language="javascript">
        // define some sample data orders
        var sampleOrder1 = {
            orderID: 'OR0001',
            orderItems: [
                { product: 'Apple', quantity: 23 },
                { product: 'Kiwi', quantity: 13 },
                { product: 'Orange', quantity: 2 },
                { product: 'Mango', quantity: 99 }
            ]
        }
        var sampleOrder2 = {
            orderID: 'OR0002',

            orderItems: [
                { product: 'Pear', quantity: 2 },
                { product: 'Mango', quantity: 400 }
            ]
        }

        // define a list of (2) sample orders
        var sampleOrdersList = {
            orders : [sampleOrder1, sampleOrder2]       
        }

        // When the DOM is ready apply the jTemplate
        $(document).ready(function() {
            // Tell jTemplates we want the div with the ID of renderedContentWillGoHere
            // to be filled with the templated
            $('#renderedContentWillGoHere').setTemplate($('#ordersListTemplateDefinition').html());

            // Combine the data in sampleOrdersList with the templateand render
            $('#renderedContentWillGoHere').processTemplate(sampleOrdersList.orders);
        });
   
    </script>
   
   
   
   
    <script type="text/html" id="ordersListTemplateDefinition">
   
        <!-- iterate over all the orders that were passed in as data
             and as each order is processed we give it an alias of currentOrder -->
        {#foreach $T as currentOrder}
   
            <!-- Output the orderID for the currentOrder we are iterating -->
            <h1> Order ID: {$T.currentOrder.orderID} </h1>
           
           
            <!-- Now we have a nested loop where we output the orderItems for the currentOrder -->
            <h4>Order Items</h4>           
            <ul>
                {#foreach $T.currentOrder.orderItems as currentOrderItem}
                    <li>{$T.currentOrderItem.product} {$T.currentOrderItem.quantity}</li>
                {#/for}
            </ul>           
           
        {#/for}
       
    </script>
       
</head>

<body>
    <div id="renderedContentWillGoHere"></div>
</body>

</html>

SHARE:

Auto Expanding Div Columns (when floated div has no set size)

Usually 2 divs side-by-side (e.g. left menu and main content) will have the left div floated left with set size, the 2nd div also float with a left margin equal to the width of the left div.

When the left div has no set size (for example if it will contain an image of unknown width) you can still float it left, but instead of floating the 'main content' div, you can set overflow: hidden; in its CSS style (real implementation via external .css).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
</head>
<body>   
    <div style="float: left">           
        <div style="width:200px; height:200px; background-color: Fuchsia"></div>        
    </div>

    <div style="overflow: hidden">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus commodo sodales faucibus. Aenean ante nunc, porta nec lacinia dignissim, eleifend ut quam. Duis quam elit, condimentum ac hendrerit et, sodales semper arcu. Phasellus justo urna, porta quis vestibulum non, fringilla non est. Sed vestibulum bibendum feugiat. Vivamus porttitor justo at sem egestas ultricies vitae et mi. Ut mattis ante sed dui viverra vel scelerisque felis bibendum. Proin nec sapien id orci egestas eleifend. Sed facilisis erat in urna ullamcorper et suscipit urna luctus. Phasellus cursus consequat odio eget auctor. Curabitur eu ante nec lacus ultrices tristique.</p>
    </div>
</body>
</html>
 

SHARE:

Disable Grey Border On Focus Selected Anchor <a> Elements

When an <a> element is selected the browser can add a grey focus border around, the CSS outline:none; can be use to prevent it on standards browsers, for IE (except IE 8 when not in compatibility mode) adding the (non-standard) hidefocus="hidefocus" attribute to the <a> element seems to work. (Unsure what older versions of IE support this.) http://help.dottoro.com/lhgdtcso.php

SHARE:

Quick and Dirty Image Loading Animation Without JavaScript

If you are display a set of images that potentially will take a while to be returned from the server (for example if pulling them out of a database via an .axd or .ashx) you can use css to to display a loading animation.

For example if you have a page of images using something like:

<img class='advertImage' alt="Car photo" src="AdvertImages.ashx?AdvertID=xxxx" width="250" height="187" />

You can define css as:

.advertImage
{
    background-position: center center;
    background-repeat: no-repeat;
    background-image: url('../img/wait.gif');
}

This css is saying "use wait.gif image as the background of the img element, put it in the centre and have only one (i.e. no-repeat)".

One of the problems is that while the image is loading some browsers (e.g. Firefox) will display the alt description and an empty image icon in addition to the loading animation which looks pretty ugly - hence the quick and dirty.

SHARE:

JavaScript Breakpoints Not Working In Visual Studio 2008

This can happen, sometimes fixed by re-installing VS or installing VS 2008 SP1. In this case it seems Javascript breakpoints do not seem to work in Visual Studio 2008 when Silverlight debugging is enabled, if you un-check the Silverlight option in the debuggers section, the JavaScript breakpoint will now be hit. Not sure if it's by design or a bug...

 

SHARE: