Page view counter

Silverlight Tips of the Day - Blog by Mike Snow

Game Programming with Silverlight

November 2008 - Posts

Silverlight Tip of the Day #75 - Where to get the Localized Languages of Silverlight 2 Tools

I am proud to announce we have released Silverlight 2 Tools localized in 8 languages! Please follow the links below to get the language of your choice.

 

Download page details: Chinese (CHS)

Bits: http://download.microsoft.com/download/2/1/8/218414F1-33DA-45B6-9007-18A1566D0D41/Silverlight_Tools.exe

 

Download page details:  Chinese (CHT)

Bits: http://download.microsoft.com/download/5/D/6/5D6B8CC0-1A92-42FF-B34C-8E255D6E8DE3/Silverlight_Tools.exe

 

Download page details: Spanish (Traditional Sort)

Bits: http://download.microsoft.com/download/2/1/B/21BA7418-C2D7-4709-9F22-A2187FAE8153/Silverlight_Tools.exe

 

Download page details: German

Bits: http://download.microsoft.com/download/E/2/2/E2251D3C-C03B-46F0-B392-D2C45DD7B4B5/Silverlight_Tools.exe

 

Download page details: French

Bits: http://download.microsoft.com/download/8/E/4/8E4EDB7F-6002-43F9-9C20-AC13EE1A6D7E/Silverlight_Tools.exe

 

Download page details: Italian

Bits: http://download.microsoft.com/download/2/B/3/2B35E5F9-7B7F-44BE-B97D-D60EB339ED4A/Silverlight_Tools.exe

 

Download page details: Korean

Bits: http://download.microsoft.com/download/7/4/5/7452614F-B836-4A88-AC37-157371EF87D5/Silverlight_Tools.exe

 

Download page details: Japanese

Bits are on  http://download.microsoft.com/download/a/1/e/a1eccacc-dfe2-45ff-80b1-c6a80c69ecb2/Silverlight_Tools.exe

 

Thank you,
--Mike Snow

Subscribe in a reader

Silverlight Tip of the Day #74 - Monitoring for App.Current Events - Startup, UnhandledException & Exit.

Ever noticed there was an event off the Page class called Loaded() that tells you when the page is loaded but none for for Exit() or Quit()?

Example for Page.Loaded():

public Page()
{
    InitializeComponent();
 
    this.Loaded += new RoutedEventHandler(Page_Loaded);
}
 
void Page_Loaded(object sender, RoutedEventArgs e)
{
    
}

One way to monitor for the Exit() event in your Page class is to subscribe to the App.Current.Exit() event. Example:

public Page()
{
    InitializeComponent();
            
    App.Current.Exit += new EventHandler(Current_Exit);
}
 
void Current_Exit(object sender, EventArgs e)
{
 
}

In addition to the Exit() event there is also:

  1. App.Current.Startup()
  2. App.Current.UnhandledException()

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #73 - Threading in Silverlight

Threads are used to run multiple jobs concurrently within the same application. In a computer with a single processor, threads are time sliced and the processor will switch between the threads being run. In a computer with two or more processors, threads are able to run at the exact same time, one on each processor.

Using threads in your Silverlight application can improve performance by increasing the responsiveness of your application. The following is a straight forward example of using threads. In this example I have:

  1. Added three TextBlocks in Page.xaml. Each TextBlock will be updated by a separate thread.
  2. Added a Button to toggle starting and stopping the threads.
  3. Declared three threads. Each thread will update their own TextBlock.
  4. Declared a counter for each thread that will show the number of times the thread was run.
  5. Added a Sleep(100) to each thread. You need to sleep some amount of time in your threads or the app will lock up.
  6. Called BeginInvoke on any element I want to update, in this case our TextBlock. This call is required since we are trying to make a change to a UI element that belongs to another thread (the main thread). 
  7. In App.xaml.cs, we set Page.Done = true in the Application_Exit event. This way the threads will quit when the browser is closed.

Preview:

App.xaml:

private void Application_Exit(object sender, EventArgs e)
{
    ((Page)this.RootVisual).Done = true;            
}

Page.xaml:

<UserControl x:Class="Threading.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="Yellow">
        <Canvas Margin="50">
            <Button Click="Button_Click" Content="Toggle Threads"></Button>
            <TextBlock x:Name="Data1" Canvas.Top="50">Thread 1</TextBlock>
            <TextBlock x:Name="Data2" Canvas.Top="100">Thread 2</TextBlock>
            <TextBlock x:Name="Data3" Canvas.Top="150">Thread 3</TextBlock>
        </Canvas>
    </Grid>
</UserControl>

Page.xaml.cs:

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.Threading;
 
namespace Threading
{
    public partial class Page : UserControl
    {
        private Thread _thread1;
        private Thread _thread2;
        private Thread _thread3;
 
        private static System.Windows.Controls.TextBlock _data1;
        private static System.Windows.Controls.TextBlock _data2;
        private static System.Windows.Controls.TextBlock _data3;
 
        private static int _count1 = 0;
        private static int _count2 = 0;
        private static int _count3 = 0;
 
        private static bool _done = true;
 
        public bool Done
        {
            get { return _done; }
            set { _done = value; }
        }
 
        public Page()
        {
            InitializeComponent();
            
            _data1 = Data1;
            _data2 = Data2;
            _data3 = Data3;
        }
 
        private void StartThreads()
        {
            _done = false;
 
            _thread1 = new Thread(DoThread1);
            _thread1.Start();
 
            _thread2 = new Thread(DoThread2);
            _thread2.Start();
 
            _thread3 = new Thread(DoThread3);
            _thread3.Start();      
        }
 
        public static void DoThread1()
        {
            while (!_done)
            {
                _count1++;
                _data1.Dispatcher.BeginInvoke(delegate()
                {
                    _data1.Text = _count1.ToString();
                 
                });
                System.Threading.Thread.Sleep(100);
            }
        }
 
        public static void DoThread2()
        {
            while (!_done)
            {
                _count2++;
                _data2.Dispatcher.BeginInvoke(delegate()
                {
                    _data2.Text = _count2.ToString();
                   
                });
                System.Threading.Thread.Sleep(100);
            }
        }
 
        public static void DoThread3()
        {
            while (!_done)
            {
                _count3++;
                _data3.Dispatcher.BeginInvoke(delegate()
                {
                    _data3.Text = _count3.ToString();
                    
                });
                System.Threading.Thread.Sleep(100);
            }
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (false == _done)
                _done = true;
            else
                StartThreads();  
        }
 
    }
}

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #72 - How to call Page.xaml.cs from App.xaml.cs

Your App class (App.xaml + App.xaml.cs) is primarily used for global events and declarations such as styles.

The primary events this class handles by default include:

  1. Application_Startup() - called when the applications starts.
  2. Application_Exit() - called when the application is exiting.
  3. Application_UnhandledException() - called when an unhandled exception has occurred.

Your Page class (Page.xaml + Page.xaml.cs) is where you will typically put the core application logic and UI declarations. Now, what if you want to communicate with your game logic in your Page class when an event such as Application_Exit() is fired in App class?

In Application_Startup() our App class creates an instance of your page class and stores it as a UIElement under the property RootVisual:

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

To illustrate the call let's add a public getter function in Page.xaml.cs:

public partial class Page : UserControl
{
    private static bool _done = false;
 
    public bool Done
    {
        get { return _done; }
        set { _done = value; }
    }
}

In order to call any public members in the page class you will have to typecast RootVisual to be a Page since by default it is a UIElement. In App.xaml.cs let's make a call to set done = true in the Page class when the application has exited:

private void Application_Exit(object sender, EventArgs e)
{
    ((Page)this.RootVisual).Done = true;            
}

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #71 – New Silverlight 2 Web Site Clean Up Check List

When creating a Silverlight application with a web site there are a number of cleanups you will want to perform. I have created a little check list here that I will maintain and update as I get new ideas.

  1. Change the Page Title. By default the title is set to your application name. Most likely, this is not what you will want. Open up your web page (I.e. default.aspx) and change the name in the <title></title> tags.

  2. Minimum Version. If you have a Silverlight 2 web site you created prior to installing the RTM version make certain to update your Minimum version of your Silverlight control in your web page to MinimumVersion="2.0.31005.0.”

  3. HTML. IIS Servers are setup by default to look for default.htm. If you use default.html to host your Silverlight app, change the extension to “.htm”.

  4. Error Message. If you use the HTML file to host your Silverlight app, change the error message form "Unhandled Error in Silverlight 2 Application" to something more specific to your site. The same thing applies to your App.xaml.cs ReportErrorToDOM() function.

  5. Install Experience – Create a custom experience for users who do not have Silverlight installed. See Tip of the Day #38 for an example on how to do this.

  6. MIME Type. If you are hosting your application on your server, open IIS and make certain you have the XAP extension registered to “application/x-silverlight-app”. See Figure 1.1 for an example.
image
Figure 1.1. XAP Mime Type Registration

Thank you,
--Mike Snow

 Subscribe in a reader

Firework Scene

If you missed ScottGu’s latest blog  check it out here!

Btw, I found this firework scene rather refreshing. Enjoy!

Fireworks

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #70 – Data Collection Support in Silverlight

Silverlight provides a number of options for data collection, storage and retrieval. In this Tip I will be walking you through various ways of doing this. You will need to add a using statement in your page to reference System.Collections;

BitArray. The BitArray is a class that you can instantiate that manages a collection of bit values which are represented as either true (1 = bit is on) or false (0 =bit is off). The following example below is an implementation of BitArray. Note that there are many different constructor options for the BitArray, this is just one.

BitArray bitArray = new BitArray(4);
 
// Add
bitArray[0] = true;
bitArray[1] = false;
bitArray[2] = false;
bitArray[3] = true;
 
// Retreive
if (true == bitArray[1])
{
    //...
}

List. The List collection allows you to store any type of data that can than be accessed by a index value. In the case below we use a string but you can replace string with any type of object you want.

List<string> test = new List<string>();
 
// Add data
test.Add("Hello");
test.Add("There");
test.Add("Goodbye");
 
// Retrieve "Goodbye"
string data = test[2];

Stack. A stack is always last in first out.  That is, the data that was inserted on the stack via a call to Push() will be the first retrieved when the call to Pop() is made. Like the List collection above, you can store any type of object in it. For our example below we are using an integer.

Stack<int> stack = new Stack<int>();
 
stack.Push(5);
stack.Push(3);
stack.Push(4);
 
// Pop the 4 off the stack.
int test = stack.Pop();

Queue. A queue is first in first out. Objects are added via the Enqueue() call and retrieved and removed via the Dequeue() call. In the example below, we enqueue three strings. Then, a call to Dequeue() removes the first string insert which was “First”. If we were to make another call to Dequeue() we would retrieve the string “Second”.

// Add data
Queue<string> queue = new Queue<string>();
queue.Enqueue("First");
queue.Enqueue("Second");
queue.Enqueue("Third");
 
// Retrieve the string "First"
string test = queue.Dequeue();

LinkedList. A LinkedList is a linked list of nodes. You have direct access to the head and tail of the list and can enumerate through the list from beginning to end. . In the example below we declare a class called Node that we store in the linked list.

class Node
{
    private int _ID;
 
    public Node(int ID)
    {
        _ID = ID;
    }
 
    public int ID
    {
        get { return _ID; }
        set { ID = value; }
    }
 
};
 
public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
 
 
        // Add Nodes
        LinkedList<Node> _list = new LinkedList<Node>();            
        LinkedListNode<Node> headNode = _list.AddFirst(new Node(432));
        LinkedListNode<Node> lastNode = _list.AddAfter(headNode, new Node(200));
        lastNode = _list.AddAfter(lastNode, new Node(451));
        lastNode = _list.AddAfter(lastNode, new Node(14));
        lastNode = _list.AddAfter(lastNode, new Node(55));
 
        // Retrieve Nodes
        foreach (Node node in _list)
        {
            int ID = node.ID;
        }
        
    }
}

Dictionary. Dictionaries store data via a key / value pair where the key is used to to identify and retrieve the item being stored and the value is the actual data being stored.

Dictionary<int, string> myData = new Dictionary<int, string>();
 
// Store Data
myData.Add(4324, "Cat");
myData.Add(331, "Dog");
myData.Add(442, "Lion");
myData.Add(3444, "Tiger");
 
// Retrieve "Lion" by passing the key 3444
string animal = myData[442];

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #69 – Silverlight 2 Developer Reference

By popular request I am posting the Silverlight Developer Reference image for Silverlight 2. This image is large (6750x4200) and will make a great poster for printing for your reference.

6750x4200 Image:

To download, right click on the image and choose “Save Picture As…”.

If the image above does not show click here to download.

Thank you,
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #68 – Great Silverlight Sessions to Watch from PDC 2008

The Professional Developer Conference of 2008 has concluded. If you were not one of the fortunate people to attend don’t fret you can still view the presentations online!

The following links below are the Silverlight related presentations from PDC I have viewed/observed. If I missed any let me know and I will add them.

  1. Microsoft Expression Blend: Tips & Tricks
  2. Microsoft Silverlight, WPF and the Microsoft .NET Framework: Sharing Skills and Code.
  3. Microsoft Silverlight 2 for Mobile: Developing for Mobile Devices.
  4. Microsoft Silverlight Futures: Building Business Focused Applications.
  5. Building an Optimized, Graphics-Intensive Application in Microsoft Silverlight.
  6. Silverlight Controls Roadmap.
  7. Microsoft Silverlight 2: Control Model

Slide Decks: Once on the site you can scroll down to the bottom of the page to obtain an link to the Power Point decks for these presentations.

Also, I just read a good summary blog on PDC. Check it out here: http://www.silverlighthack.com/post/2008/10/29/PDC-2008-Silverlight-2-WrapUp.aspx

Enjoy!
--Mike Snow

 Subscribe in a reader

Silverlight Tip of the Day #67 – Silverlight Performance Tips

After watching Seema’s PDC talk on Building an Optimized, Graphics-Intensive Application in Microsoft Silverlight I thought it would be useful to summarize what I learned.

1. Debugging

The following items will help you debug performance in your Silverlight application:

  • EnableRedrawRegions – Turn on this debug setting to see what and where rectangles are being redrawn within your application. When enabled you can see what is painted because the repaint region is colored in blue, yellow or pink. This property is set when you create your Silverlight plug-in.

    Example:

<div style="height:100%">
    <asp:Silverlight ID="Xaml1" EnableRedrawRegions="true" 
     
EnableFrameRateCounter="true" runat="server" PluginBackground="Transparent" 
     
Windowless="true" Source="~/ClientBin/Snowflakes.xap"
     
MinimumVersion="2.0.30523" Width="100%" Height="100%" />
</div>


  • MaxFrameRate - To see what components of your application are having the most adverse affect on the performance you can set the MaxFrameRate for your application. You can then experiment with adding and removing components to your application to see how the performance changes. To do set the following properties highlighted below:

<div  style="height:100%">
    <asp:Silverlight ID="Xaml1" MaxFrameRate="10"  EnableFrameRateCounter="true"  
      
runat="server" PluginBackground="Transparent" Windowless="true"
      
Source="~/ClientBin/Snowflakes.xap" MinimumVersion="2.0.30523" Width="100%" 
       Height
="100%" />
</div>

2. Media Pipeline

For each frame and each pixel when drawing a media element Silverlight:

  1. Decodes the image.
  2. Performs a YUV Convert
  3. Resize if media is not at its original size.
  4. Blend if needed (for example: overlays such as icons, scroll bars, etc.)
  5. Draw

Few notes on performance:

  1. Encode the media element at the minimum frame rate you can accept.
  2. Display your media element at its original size to avoid resize calculations. If you want a different size, first re-encode the media to the size you want to display it at. This will save on bandwidth and interpolation of every pixel each frame.
  3. Blending with media is expensive, avoid overlays where possible.
  4. For media, use a frame of around 60 for best results.

3. Text Rendering

Text rendering is expensive and should be avoided when possible. The following actions triggers text to be re-rendered:

  1. Translating or scaling the text
  2. Media on the page.
  3. Animation on the page.

Consider using a bitmap in replace of text for any intensive animation.

4. Silverlight Control.

  1. Running Silverlight with “Windowless = false” is faster than “Windowless=true”. Only set it to true if you need to overlay HTML content on top of your Silverlight application.
  2. Do not set the Silverlight plug-in control to PluginBackground="Transparent" unless absolutely necessary. This adds costs to each render call forcing it through the blending pipeline. If your goal is to match the Silverlight controls background color with your HTML background color simply set the background style color of your HTML page to match the Silverlight control. In the example below we set the body background to black. Make certain the size of the Silverlight control matches that which you declare in Page.xaml otherwise the difference will be represented by a white border.

<body style="background-color:Black;margin:0;">
    <form id="form1" runat="server" style="height:100%;">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <div>
            <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/FastAnimation.xap" MinimumVersion="2.0.30523" Width="800px" Height="600px" />
        </div>
    </form>
</body>

Final Notes:

  • Silverlight gives you full control of the UI thread. Use it wisely.
  • Don’t bloat your code, especially your XAML.
  • Turn off your application (stop threads, background calculation, etc.) when not needed.
  • When brushes are resized a new texture is allocated for the brush. Keep this in mind when resizing!
  • When Silverlight performs animation it only redraws the dirty rectangles. Avoid large scale animations.
  • Set the frame rate of your application to only be what is needed. For video, you will want around 60. For animation, around 20-30.

Thank you,
--Mike Snow

 Subscribe in a reader