Page view counter

Silverlight Tips of the Day - Blog by Mike Snow

Game Programming with Silverlight

January 2009 - Posts

Silverlight Tip of the Day #89 – How to use String Resources

In this Tip I will be showing you how to place hard coded strings into a resource area. This is a common best practice for software development that makes it much easier to manage the strings in your application.

To start, open up your App.xaml file and add a reference to the MSCORLIB library as seen highlighted here.

<Application xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns
:x=http://schemas.microsoft.com/winfx/2006/xaml 
xmlns:clr
="clr-namespace:System;assembly=mscorlib"
x:Class="TestApp.App">

One place you can add all your strings is under the Application.Resources section in your App.xaml. To illustrate this, I have added one string resource that can be referenced through the key “MyName”.

<Application.Resources>
    <clr:String x:Key="MyName">Mike Snow</clr:String>
</Application.Resources>

Finally, open up Page.xaml and add a TextBlock. Set the text of this TextBlock to point to the string resource we just added. This can be done by using the syntax Text=”{StaticResource MyName}” as seen here:

<TextBlock Text="{StaticResource MyName}"></TextBlock>

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #88 – How to handle image AG_E_NETWORK_ERROR errors

If you have ever worked with images while developing and running Silverlight app you have more than likely come across the AG_E_NETWORK_ERROR  exception. This exception is thrown if an image was not able to load for whatever reason (I.e. it couldn’t be found, corrupt, etc.).

In order to prevent your users from seeing this error it’s important to monitor for the ImageFailed event for each image your try to load.

The following code demo’s how to accomplish this for an image.

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
        LoadImage("http://www.mysite.com/grass.png");
    }
 
    private void LoadImage(string url)
    {
        Image img = new Image();
        img.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(img_ImageFailed);
        Uri imageUri = new Uri(url, UriKind.RelativeOrAbsolute);
        ImageSource imgSource = new BitmapImage(imageUri);
        img.SetValue(Image.SourceProperty, imgSource);
        LayoutRoot.Children.Add(img);
    }
 
 
    void img_ImageFailed(object sender, ExceptionRoutedEventArgs e)
    {
        // Handle the error here
    }

In the img_ImageFailed() event add the custom code you will need to handle this error.

 

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #87 – How to Change the Startup Class

When a Silverlight application is launched the entry point is a class that inherits from System.Windows.Application. By default, when you create a new Silverlight application project, this would be your App class which gets defined in App.xaml.cs. You can, however, change which startup class you want to use. In fact, if you do not plan to use XAML at all you can reduce the size of your application by deleting the Page and App classes including the XAML and code behind files.

To accomplish this follow these steps:

Step 1. Create a new Silverlight application project adding a new ASP.net web project to host the Silverlight app.

Step 2. Delete App.xaml and Page.xaml (the CS files will be deleted also).

Step 3. Create a new class and call it StartupTest.cs

Step 4. Modify your new class to inherit from Application as seen here:

public class StartupTest : Application
{
    public StartupTest()
    {
    
    }
}

Step 5. Right click on your Silverlight application project in the Solution Explorer of VS. From the context menu choose Properties. This will bring up the Properties dialog. Click on the Silverlight tab at the top-left and change the Startup object to be your class as seen circled here:

image

Step 6. Go back to your StartupTest class. Add an event to monitor for when the application has started. You don’t want to do anything until after this event has started.

public class StartupTest : Application
{
    public StartupTest()
    {
        this.Startup += new StartupEventHandler(StartupTest_Startup);
    }
 
 
    void StartupTest_Startup(object sender, StartupEventArgs e)
    {
    }        
}

Step 7. The Application.RootVisual is root pointer to the main application UI. You will need to create this object to point an object such as a Grid or Canvas control. Once created, you can add additional controls to the children as you see fit. In the example below, I have created a Canvas as the root and configured its background color to be black, its width to be 800 and height to be 600. Also, I have added a Textbox to the Canvas control.

void StartupTest_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new Canvas();
 
    ((Canvas)this.RootVisual).Width = 800;
    ((Canvas)this.RootVisual).Height = 600;
    ((Canvas)this.RootVisual).Background = new SolidColorBrush(Colors.Black);
 
    TextBlock tb = new TextBlock();
    tb.Foreground = new SolidColorBrush(Colors.White);
    tb.FontSize = 20;
    tb.Text = "NO XAML NEEDED!!!";
 
    ((Canvas)this.RootVisual).Children.Add(tb);
}        

Step 8. Run the application and you will see the following image rendered in your browser:

image

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #86 – How to Load External Images

In Tip of the Day #84 I discussed the importance of being able to load controls from server side components (DLL’s) on demand rather than packaging everything together for one large client side download. The same principle applies to images. Let’s say your game has a large library of images that it needs for the game. Not all of these images will be needed at the start of the game. In this tip I will show you how to dynamically load these image resources from the server as needed.

To download an image from a server start by creating a BitmapImage. You will need to add a using statement to reference System.Windows.Media.Imaging. After you have created a BitmapImage point its UriSource to the absolute path of the image file you want to download from the Internet. To illustrate this I have used http://www.silverligthdev.net/images/myImage.png. Next, set the Source of your Image control to point to the BitmapImage.

Example XAML that contains the Image you will load:

<Canvas x:Name="LayoutRoot" Background="White">
    <Image x:Name="MyImage"></Image>
</Canvas>

The following C# code shows you how to load the image source from a file on a server. When the image is 100% loaded the event ImageOpened is fired.

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
 
        BitmapImage bi = new BitmapImage();
        bi.UriSource = new Uri("http://www.silverlightdev.net/images/blogImages/Sample.png");
        MyImage.Source = bi;
 
        MyImage.ImageOpened += new EventHandler<RoutedEventArgs>(MyImage_ImageOpened);
    }
 
    void MyImage_ImageOpened(object sender, RoutedEventArgs e)
    {
        // Image load complete.
    }
}

Thank you,

--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #85 – How to Save $$ on the Silverlight MIX Conference
image

A $400 discount is available for a limited time for customers who register for MIX by Feb 13th. To receive the discount you should use the MIX09offer RSVP code at the beginning of the registration site.

To register go here: https://register.visitmix.com/registrationselect.aspx

MIX is a great opportunity to connect with Microsoft and industry thought-leaders in the web space. In addition, you can learn more about the future of Microsoft’s web platform and tools, network with industry professionals and participate in a wide variety of sessions over the course of four days.

I hope to see you there!
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #84 – How to Dynamically Load a Control from a DLL

If you have a large game or application it might be wise to break it up into smaller components (DLL’s) that can be downloaded to the client from the server as needed. This way your customers are not stuck waiting for a large download to complete when they first connect to your application on the web.

In this tip I will show you how to package Silverlight controls into a DLL and place them on your web server. Then, I will show you how to have the client download the DLL, create and instance of the Silverlight control from the DLL and then to add the control to your Silverlight application.

Step 1. Create a Silverlight Component DLL.

To start, create a new Silverlight Class library. This can be done through the menu in VS: File | New->Project. In Project Types expand the Visual C# node and choose Silverlight. From the Templates pane on the right of this dialog choose Silverlight Class Library. Give the project a name (such as “Mage”) and click OK on the dialog when ready.

In the Solution Explorer right click on your Class node and choose Add->New Item. This will bring up the Add New Item dialog. Select Silverlight User Control, give it a name (such as “Mage.xaml”) and click OK when ready.

Add whatever content you want to this control. For my demo purposes I have simply added an image of a mage character.

<UserControl x:Class="Mage.Mage"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
    Width="96" Height="96">
    <Canvas>
        <Image Source="mage.png"></Image>
    </Canvas>
</UserControl>

Ctrl+Shift+B to build the project. This will put your component in a DLL in your bin folder such as bin\Mage.dll.

Step 2. Create a Silverlight Application.

Now that you have your Silverlight component built and ready to go it’s time to create a Silverlight application that will load and display the component. Create a Silverlight application by selecting in the menu File->New Project and choosing Silverlight Application this time instead of Silverlight Class Library. Give the project a name (such as MyGame) and click OK when ready.

Copy the Silverlight component DLL that you built earlier (such as Mage.dll) to your Web site folder (such as MyGame\MyGame.Web).

Step 3. Download and Display the Silverlight Control

The following code below shows you how to load and display the Silverlight control. Few things to note:

  1. Add a using statement to reference System.Reflection since they component we are creating is declared as an Assembly object.
  2. Use the WebClient component to open a asynchronous read of the DLL.
  3. Make certain you point to the absolute path of your DLL. An absolute path uses the full URL.
  4. Once the download is complete the assembly is loaded and an instance of the control is created.
  5. Finally the control is added to the root level of the application.

The result, a nice little mage is rendered:

image

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;
using System.Reflection;
 
namespace MyGame
{
    public partial class Page : UserControl
    {
        private Assembly _mageComponent;
 
        public Page()
        {
            InitializeComponent();
 
            LoadMageComponent();
        }
 
        private void LoadMageComponent()
        {
            WebClient downloader = new WebClient();
            downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
 
            string component = "Mage.dll";
            string absoluteUri = System.Windows.Application.Current.Host.Source.AbsoluteUri;
            string path = absoluteUri.Substring(0, absoluteUri.IndexOf("ClientBin")) + component;
 
            downloader.OpenReadAsync(new Uri(path, UriKind.Absolute));
        }
 
        void downloader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            AssemblyPart assemblyPart = new AssemblyPart();
            _mageComponent = assemblyPart.Load(e.Result);
            UserControl control = (UserControl)_mageComponent.CreateInstance("Mage.Mage");
            LayoutRoot.Children.Add(control);
        }
    }
}

Thank you,
--Mike Snow

 Subscribe in a reader

Presidential Inauguration to be streamed live in Silverlight

On Tuesday, January 20th the Presidential Inauguration will be available through the Inauguration Committee web site. They will be streaming live with the help Microsoft Silverlight. The event, starting with the swearing-in ceremony, starts at 11:30 AM EST in Washington DC.

Details on the stream are here: http://www.pic2009.org/blog/entry/watch_the_swearing-in_ceremony_on_the_web/

So if you are not one of the many who will be hanging out in Washington DC visit the Inauguration Committee web site  to get more details on this viewing this historical event live through Silverlight.

Thanks,
--Mike

Silverlight Tip of the Day #83 – Go to MIX09

MIX 2009

MIX Is just around the corner and if you haven’t already registered I highly recommend you do! This is one event I look forward to the most each year. I attended last year and I had the most incredible experience learning about Silverlight and meeting so many intelligent people (OK, and I had a ton of fun playing Poker too).

If you are not familiar with what MIX is, MIX is a conference that gathers both web developers and web designers together who want to take their skills to the next level. There are numerous sessions you can attend that teach you the latest and great ways to build the worlds top most innovative web sites.

This year MIX is held in Las Vegas from March 17th – March 20th so mark you calendar! Scott Guthrie, our Corp VP, will be the keynote speaker. You will not want to miss what he has to say.

MIX 2009

Current sessions include (see details here):

  • Building an Optimized, Graphics-Intensive Application for Microsoft Silverlight (Seema Ramchandani).
  • Building Data-Driven Scalable AJAX Web Pages
  • Building Microsoft Silverlight Applications with Eclipse (Shawn Wildermuth)
  • C# for Designers
  • Deep Dive into Microsoft Silverlight Graphics (Seema Ramchandani, Marshall Agnew)
  • Escaping Flatland in Application Design: Visualizing Data (Peter Eckert, Eric Gould Bear)
  • From Concept to Production: Design Workflow with Microsoft Expression Studio (Christian Schormann)
  • Go Beyond Best Practices: Evolving Next Practices to Prosper in the 21st Century (Lou Carbone)
  • Go Deep with Microsoft Silverlight Controls
  • Going Inside Microsoft Silverlight: Exploring the Core CLR (Brandon Bray)
  • High-Speed RIA Development with the Microsoft Silverlight Toolkit
  • How Razorfish Lights Up Brand with Microsoft SharePoint
  • Improving UX through Application Lifecycle Management (Chris Bernard)
  • Integrating Microsoft Expression Blend with Adobe Creative Suite (Joanna Mason)
  • Interaction Techniques Using the Wii Remote (and Other HCI Projects) (Johnny Lee)
  • Interactive Prototyping with DHTML (Bill Scott)
  • Live Framework and Mesh Services: Live Services for Developers
  • Mesh-Enabled Web Applications
  • Microsoft Expression Web: No Platform Left Behind (Steve Guttman)
  • Optimizing Performance for Microsoft Expression Encoder (James Clarke)
  • RESTful Services for the Programmable Web with Windows Communication Foundation (Ron Jacobs)
  • The Future of Microsoft Expression Blend (Douglas Olson)
  • The Way of the Whiteboard: Persuading with Pictures
  • Touch and Gesture Computing, What You Haven't Heard (Joseph Fletcher)
  • Visual Design with Microsoft Expression Blend (Celso Gomes)
  • Web Form Design
  • What's New in Microsoft Silverlight 3 (Joe Stegman)
  • What's New in Microsoft Silverlight 3 Media (Larry Olson)
  • Wireframes That Work: Designing (Rich Internet) Applications

I sincerely hope to see you there.

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #82 – How to Implement Double Click

Silverlight currently has full mouse support for single click. However, double click is a another story. In this tip I will show you how to implement double click. You can apply this technique for an individual control or even your entire page.

The key thing to do is to start a DispatcherTimer timer once a left mouse click event has been received. If another mouse click is intercepted before the double click time interval has passed then a double click has occurred. This interval is typically set to be around 200 milliseconds. Once 200 milliseconds has passed the timer is stopped and disabled until another mouse click is received.

To start, let’s create our timer and add a listener for the MouseLeftButtonDown event.

DispatcherTimer _doubleClickTimer;
Image _lastImage = null;
 
public Page()
{
    InitializeComponent();
   
    _doubleClickTimer = new DispatcherTimer();
    _doubleClickTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
    _doubleClickTimer.Tick += new EventHandler(DoubleClick_Timer);
 
    this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);
}
 
// too much time has passed for it to be a double click.            
void DoubleClick_Timer(object sender, EventArgs e)
{
    _doubleClickTimer.Stop();
}

Now, in the Page_MouseLeftButtonDown() method we:

  1. Check if the timer is enabled.
  2. If it is enabled already, then we have already clicked once and have made a double click.
  3. If is it not enabled start the timer.
void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (_doubleClickTimer.IsEnabled)
    {
        // a double click has occured
        _doubleClickTimer.Stop();
 
        Image catImg = new Image();
        Uri uri = new Uri("cat.png", UriKind.Relative);
        ImageSource imgSource = new
            System.Windows.Media.Imaging.BitmapImage(uri);
        catImg.Source = imgSource; 
 
        catImg.SetValue(Canvas.LeftProperty,(double) e.GetPosition(LayoutRoot).X-90);
        catImg.SetValue(Canvas.TopProperty, (double)e.GetPosition(LayoutRoot).Y-113);
 
        if(null != _lastImage)
            MainCanvas.Children.Remove(_lastImage);
        
        MainCanvas.Children.Add(catImg);
        _lastImage = catImg;
 
    }
    else
    {
        _doubleClickTimer.Start();
    }
}

Here is a demo of this code:

 

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #81 – How to Scale your Silverlight Control

One often unknown property your Silverlight control contains is a property called ScaleMode. This property allows you to specify how the controls within your Silverlight application are scaled when your Silverlight control is resized.

For example, if the width or height of your Silverlight control is set to be a percentage of your browser web page than when the browser page is resize so will your Silverlight control.

The three options available for the property ScaleMode are:

  1. None – No scaling is performed
  2. Stretch- Stretching is performed to fill the browser horizontally and vertically.
  3. Zoom – Scaling is performed to proportionally fill the browser.

The following is an example of how to set this ScaleMode to Stretch in your ASPX page:

<asp:Silverlight ID="Xaml1" ScaleMode="Stretch" runat="server" Source="~/ClientBin/SilverlightApplication52.xap" MinimumVersion="2.0.31222.0" Width="100%" Height="100%" />

Before a browser resize:

image

After a browser resize (notice that the button scales):

image

Thank you,
--Mike Snow

Subscribe in a reader

Silverlight Tip of the Day #80 – How to Crop an Object

If you only want to display part of an object you can do this through the Clip property. The clip that you define is the area of the object that you want to be rendered. For example, say you have a rectangle defined like this:

<Rectangle Fill="DarkGoldenrod" Height="100" Width="200" StrokeThickness="3" Stroke="Black"></Rectangle>

 image

If you only want to show part of the rectangle you can apply a clip region to it like this:

<Rectangle Fill="DarkGoldenrod" Height="100" Width="200" StrokeThickness="3" Stroke="Black">
            <Rectangle.Clip>
                       <EllipseGeometry Center="0,0" RadiusX="80" RadiusY="80" />               
            </Rectangle.Clip>
</Rectangle>

image

You will noticed I used an EllipseGeometry and centered it in the upper-left corner. The result is a 1/4 circle 80x80 in size. In addition to EllipseGeometry you can also use:

  1. RectangleGeometry
  2. GeometryGroup
  3. LineGeometry
  4. PathGeometry

Thank you,
--Mike Snow

Subscribe in a reader

Silverlight Tip of the Day #79 – How to Disable HTML DOM Access from your Silverlight Application.

If you would like to disable your Silverlight application from having access to your browser DOM you can do so through the parameter called EnableHtmlAccess. For example, to disable the access in your HTML page that hosts your Silverlight component you would add this parameter to your Silverlight control in your HTML file:

<param name="enablehtmlaccess" value="false"/>

If your Silverlight application tried to call the following method to set a cookie:

private void SetCookie(string key, string value, double daysToExpire)
{
    DateTime expireDate = DateTime.Now + TimeSpan.FromDays(daysToExpire);
    string newCookie = key + "=" + value + ";expires=" + expireDate.ToString("R");
    HtmlPage.Document.SetProperty("cookie", newCookie);
}

You would get this error stating the DOM/scripting bridge is disabled:

image

Thank you,
--Mike Snow

Subscribe in a reader

Silverlight Tips of the Day - Summary Outline

The purpose of this post is to create an outline summary all the blogs from my Silverlight Tips of the Day blog. Hopefully this will be easier than paging through multiple pages of blogs to find what you need. I will be keeping this list up-to-date as I add more blogs so feel free to bookmark this page!

Also, if you have any ideas or suggestions for other tips don’t hesitate to contact me at msnow@microsoft.com or post a comments to this blog. 

In Order by Category.

Animation

Browser

 Controls

Data

Debugging

Events

Game Development

Images

Isolated Storage

Mouse and Keyboard

Networking

Performance

Project and Tools

 Resources

 Sound and Video

 Styles

 Text

 Threading

 Utilities

 Web Service

 XAML

In order by Tip #.

Other:

Thanks to everyone for there comments and contributions to these tips.

Thank you,
--Mike Snow

 Subscribe in a reader