Quickly Take Down an ASP.NET Web Site

If you need to temporarily take down an ASP.NET (2.0+) web site you can simply add a file called app_offline.htm to the root of the site. The content of the app_offline.htm could contain a message such as "Site currently undergoing maintenance" or similar.

When you add the file to the root, the server unloads the app domain, when the file is remove (or renamed for example) the next request that comes in will restart the app domain, etc...

SHARE:

Countdown To Christmas 2009 Silverlight 3 app

For a bit of Silverlight 3 fun:

 



Use\install at: http://www.dontcodetired.com/live/christmascountdownbeta/

There are some things which need improving such as resizing when run out of browser, abilty to sort/hide/filter data etc.

SHARE:

Silverlight 3 WritableBitmap pixel colour values

Rather than taking an array of Color objects, the WritableBitmap.Pixels property holds an array on ints which represent premultiplied ARGB colour values. To set a given pixel to a given colour you have to take the alpha, red, green and blue values and convert them to a premultiplied ARGB int value.

The following code contains some helpers/extension methods to make the process bit easier, for example to set every pixel to red:

for (int index = 0; index < bmp.Pixels.Length; index++)
{
   Color myColour = new Color() { A = 255, R = 255, G = 0, B = 0 };
   bmp.Pixels[index] = myColour.ToWritableBitmapPixelValue();
}

 or using the Fill extension method:

bmp.Fill( new Color() { A = 255, R = 255, G = 0, B = 0 } );

WritableBitmapHelper class listing

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace BitmapAPI
{
    /// <summary>
    /// Helper methods\extension methods for dealing with WritableBitmap,
    /// in real world implementation you'd probably choose to separate the
    /// extension methods iinto separate static classes;
    /// eg WritableBitmapExtensions & ColorExtensions
    /// </summary>
    public static class WritableBitmapHelper
    {
        /// <summary>
        /// Converts ARGB byte values to an integer
        /// Based on info found at:
        /// http://blogs.silverarcade.com/silverlight-games-101/15/silverlight-writeablebitmap-pixel-format-in-silverlight-3/
        /// </summary>
        /// <param name="alpha">Alpha transparency: 0=transparent  255=solid</param>
        /// <param name="red">Amount of red: 0 to 255</param>
        /// <param name="green">Amount of green: 0 to 255</param>
        /// <param name="blue">Amount of blue: 0 to 255</param>
        /// <returns>An integer representing an ARGB color</returns>
        public static int CalcWritableBitmapPixelValue(byte alpha, byte red, byte green, byte blue)
        {
            // Calc premultiplier once only. We need to use premultiplied ARGB32
            // rather than convential ARGB.
            double alphaPreMultiplier = alpha / 255d;

            // Premultiply rgb values with alpha
            byte r = (byte)(red   * alphaPreMultiplier);
            byte g = (byte)(green * alphaPreMultiplier);
            byte b = (byte)(blue  * alphaPreMultiplier);

            return (alpha << 24) | (r << 16) | (g << 8) | b;
        }



        /// <summary>
        /// Extension method to convert a System.Windows.Media.Color to an integer value.
        /// </summary>
        /// <param name="color">The System.Windows.Media.Color to convert</param>
        /// <returns>An integer representing the ARGB values of <paramref name="color"/></returns>
        public static int ToWritableBitmapPixelValue(this Color color)
        {
            return CalcWritableBitmapPixelValue(color.A, color.R, color.G, color.B);
        }



        /// <summary>
        /// Extension method to 'fill' a WriteableBitmap with a given solid color
        /// </summary>
        /// <param name="bmp">The WriteableBitmap to fill</param>
        /// <param name="color">The Color to fill with</param>
        public static void Fill(this WriteableBitmap bmp, Color color)
        {
            for (int i = 0; i < bmp.Pixels.Length; i++)
            {
                bmp.Pixels[i] = color.ToWritableBitmapPixelValue();
            }
        }

    }
}

 

 

 

SHARE:

Silverlight 3 3D Animation Using PlaneProjection and Storyboards

While SL3 doesn't add full 3D support, you can now transform elements in a 3D fashion.

The following videos are recommended (and form the basis of this example) but I've used simple opacity rather than transforming an element off the screen:

http://silverlight.net/learn/learnvideo.aspx?video=187308

http://silverlight.net/learn/learnvideo.aspx?video=189248

 

The new PlaneProject allow you to 'skew' an element in X, Y and Z dimensions. UI elements now have a Projection property which can contain a PlaneProjection:

<Grid.Projection>
  <PlaneProjection x:Name="HeadsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
</Grid.Projection>

The example below uses 2 grids containing a circle (the coin face) and text "Heads" or "Tails". There are 2 storyboards, the 1st rotates the heads to tails, the 2nd animation tails to heads. The storyboards call each other wheneach one finishes using the Completed event of the storyboard.

The code behind looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace _3DCoinFlip
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
      
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            // Automatically start the 1st storyboard when the page loads
            FlipToTails.Begin();
        }
       
        private void FlipToTails_Completed(object sender, EventArgs e)
        {
            // When the head-->tails animation completes, start the tails-->heads animation
            FlipToHeads.Begin();
        }

        private void FlipToHeads_Completed(object sender, EventArgs e)
        {
            // When the tails-->heads animation completes, start the head-->tails animation
            FlipToTails.Begin();
        }
    }
}

 And the XAML:

<UserControl x:Class="_3DCoinFlip.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:DesignWidth="640" d:DesignHeight="480"
    Loaded="UserControl_Loaded" >
    <UserControl.Resources>
       
        <Style TargetType="Grid" x:Key="CoinFace">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="200"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="CoinText">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="FontSize" Value="48"/>
        </Style>
       

        <Storyboard x:Name="FlipToTails" Completed="FlipToTails_Completed" >
            <!-- heads side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="HeadsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
            </DoubleAnimationUsingKeyFrames>



            <!-- Tails Side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="TailsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="270"/>
                <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="Tails"
                                           Storyboard.TargetProperty="Opacity">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01.01" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>



        <Storyboard x:Name="FlipToHeads" Completed="FlipToHeads_Completed">
            <!-- tails side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="TailsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
            </DoubleAnimationUsingKeyFrames>



            <!-- heads Side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="HeadsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="270"/>
                <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="Heads"
                                           Storyboard.TargetProperty="Opacity">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01.01" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <StackPanel>
            <Grid>
                <Grid Name="Heads" Style="{StaticResource CoinFace}">
                    <Grid.Projection>
                        <PlaneProjection x:Name="HeadsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
                    </Grid.Projection>
                    <Ellipse Stretch="Fill" Fill="Silver"/>
                    <TextBlock Style="{StaticResource CoinText}">Heads</TextBlock>
                </Grid>
                <Grid Name="Tails" Style="{StaticResource CoinFace}" Opacity="0">
                    <Grid.Projection>
                        <PlaneProjection x:Name="TailsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
                    </Grid.Projection>
                    <Ellipse Stretch="Fill" Fill="Gold"/>
                    <TextBlock Style="{StaticResource CoinText}">Tails</TextBlock>
                </Grid>
            </Grid>
        </StackPanel>
    </Grid>
</UserControl>

 

SHARE:

Silverlight 3 - Detecting Network Availability

One of the new SL3 features is the ability to test if there is a network connection currently active. This complements the out of browser experience by letting an app use local (isolated) storage when off-line, and when a network connection becomes available, upload data to a central server.

To be informed when the network changes:

System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += (sender, e) => txtNetStatus.Text = "Network available: " + System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable().ToString();

This example uses a lambda expression as a shortcut (rather than having a separate method); when the network status changes, we set the text of txtNetStatus to 'Network available: True' or 'Network available: False' depedning on the (boolean) result of GetIsNetworkAvailable().

SHARE:

Silverlight 3 Out Of Browser Install Errors

If a user attempts to install a SLOOB app when it is already installed an InvalidOperationException is thrown with the message "Application is already installed.". We can wrap in a try..catch to handle this:

 try
{
    Application.Current.Install();
}
catch (InvalidOperationException ex)
{
    MessageBox.Show(ex.Message);
}

 

Or better yet, remove the install button from the UI if the application is already installed:

 

if (Application.Current.InstallState == InstallState.Installed)
    btnInstall.Visibility = Visibility.Collapsed;
else
    btnInstall.Visibility = Visibility.Visible;

SHARE:

Silverlight 3 Out Of Browser Automatic Updates

When running a Silverlight 3 application out of browser (OOB) {or SLOOB=Silverlight Out Of Browser} you can enable the automatic download\install of updated versions.

This is not an automatic feature and requires some (simple) coding on the developers part.

In the App.xaml.cs add a callback for the CheckAndDownloadUpdateCompleted event (the example below uses a lambda but you could use a separate method with the signature void App_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e).

public App()
{
    this.Startup += this.Application_Startup;
    this.Exit += this.Application_Exit;
    this.UnhandledException += this.Application_UnhandledException;

    // Add callback to be executed when the check (and possible download) has been performed
    this.CheckAndDownloadUpdateCompleted += (sender,  e) =>
    {
        if (e.UpdateAvailable)
            MessageBox.Show("Update downloaded, plese restart to take effect.");
    };

     
    InitializeComponent();
}

 Next add a call to check for updates, this can be placed in the Application Startup event handler or you could have a "Check for updates" button in th U.

 private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new MainPage();
    this.CheckAndDownloadUpdateAsync();
}

Now, every time the app start an update check will be performed, and if there is an updated version available it will be downloaded asynchronously. Once download the user will get the message box advising them to restart the app to start using the new version. The download\update just happens if available and there is currently no mechanism to allow the user to opt-out of an update.

 

SHARE:

Running Silverlight 3 Application Out Of Browser

This is pleasantly simple to do :)

In response to a user action (clicking a button, etc.) add the following code: Application.Current.Install(); e.g.

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    Application.Current.Install();
}

Configure the application to run out of browser (OOB):

In the project properties page, tick the"Enable running application out of the browser"

 

The Out-Of-Browser Settings button now becomes enabled: this lets you specify OOB window and shortcut names, description, and an application icon in 4 different sizes.

You can un-install an OOB app by running it (from the desktop or programs menu) and right-clicking and choosing "Remove this application".

SHARE: