Introduction
Silverlight is great, lots of things to do with Templates and UserControls. But, what if you want to make a game, or just a cool demo, with snow for the holidays? What is the use of XAML then? Let's get rid of it.
Creating a new Silverlight project
Start off by creating a new Silverlight project like you're used to. Click on File->New->Project... in the menu, or press Ctrl+Shift+N.
Select Silverlight Application from the Silverlight Project types, and give it a fun name. I called mine SilverlightWithoutXaml. And, press the OK button.
You could create a dynamic data driven ASP.NET MVC Web project for hosting your great Silverlight game, but for the simplicity of this article, we're picking the "Automatic generate" option from the dialog.
Removing the XAML
Now, wait for a second to let Visual Studio create the nice XAML files we're going to delete in a few moments... Visual Studio shows a project like in the picture below. Just go on and delete both XAML files now. The .cs files will be deleted automatically.
Besides some config and generated files, the project is empty now. Because Silverlight without code won't do much, we're going to add a new class now. Right-click the project and go to Add->Class... You can name it anything you want, but in the example, I've called it WithoutXamlApp . |
|
Silverlight needs a place to start the application. Therefore, the class that has just been added to the solution needs to be derived from System.Windows.Application
.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Collections.Generic;
namespace SilverlightWithoutXaml
{
public class WithoutXamlApp : Application
{
}
}
Next, we need to add an HTML file to host the Silverlight control. Add an HTML file the same way you just did for the class. Right-click the project and Add->New Item... Select the HTML-file template and name it StartPage.htm or anything you're more comfortable with. Add the following to the body of the HTML file:
<object id="ID" type="application/x-silverlight-2" width="600" height="400">
<param name="source" value="bin/debug/SilverlightWithoutXaml.xap" />
<param name="background" value="#00000000" />
</object>
Configuring the project
To run the application, you need to make a few changes in the properties of this project. Right-click the project and go to Properties. Make sure the Startup object is set to SilverlightWithoutXaml.WithoutXamlApp
.
Go to the Debug tab and press the button with the ellipses next to the Specific Page radio button. Select StartPage.htm from the dialog and press OK. Great! Hit F5 to build and run the application to see if it works. If you get a white HTML page in your browser with a black square and the Silverlight loading animation in the middle, you're good. If not, read the above again, or post a comment below and I'll try to help and fix your errors.
Time for fun
OK, now you've got a XAML-less Silverlight application! What's next? I know, you saw that screenshot at the top and you're thinking: "Hey! I want white dots on my Silverlight app too!” Let's add some.
Before we can start our animation loop and do fun stuff, we have to wait until Silverlight is done loading and starting the application. Luckily for us, an event is fired when this happens. The first thing of the application class that is run by Silverlight is the constructor. This would be the perfect place to register to the startup-event. Add the following code to the WithoutXamlApp
class:
public WithoutXamlApp()
{
this.Startup += new StartupEventHandler(WithoutXamlApp_Startup);
}
void WithoutXamlApp_Startup(object sender, StartupEventArgs e)
{
}
Let's add a canvas to paint on. This canvas needs to be assigned to this.RootVisual
of the application. The RootVisual
is a UIElement that holds the main UI for the application, the root of the visual tree. Add the following code to the WithoutXamlApp_Startup
method. This will initialize the root with a Canvas
with a black background.
this.RootVisual = new Canvas()
{
Background = new SolidColorBrush(Colors.Black)
};
For the animation loop, we're going to use a DispatcherTimer
. This thing launches a Thread when started, and fires an event at a given interval. The great thing about this timer is that it’s very easy to implement. Add the following four lines code to the WithoutXamlApp_Startup
method:
DispatcherTimer Timer = new DispatcherTimer();
Timer.Interval = new TimeSpan(300);
Timer.Tick += new EventHandler(Timer_Tick);
Timer.Start();
The interval of 300 I've chosen gives a smooth animation. The event handler for Timer.Tick
is shown below. The last line kicks off the time. From that time on, the Tick
-event is called every 0.03 seconds.
void Timer_Tick(object sender, EventArgs e)
{
}
We're almost there. The final piece of code consists of three parts. One that loops through and updates all the dots and remembers those that need to be removed from the visual tree, the second that performs the actual removal of the dots, and the last one that adds a new dot at a random X-location to the Canvas
. Let's take a look:
void Timer_Tick(object sender, EventArgs e)
{
List<Ellipse> ElToRemove = new List<Ellipse>();
foreach (Ellipse child in ((Canvas)this.RootVisual).Children)
{
if (Canvas.GetTop(child) > 400)
ElToRemove.Add(child);
else
{
Canvas.SetTop(child, Canvas.GetTop(child) + 2);
Canvas.SetLeft(child, Canvas.GetLeft(child) +
(rnd.NextDouble() * 4) - 2);
}
}
foreach (Ellipse item in ElToRemove)
{
((Canvas)this.RootVisual).Children.Remove(item);
}
int size = rnd.Next(3, 15);
Ellipse el = new Ellipse()
{
Width = size,
Height = size,
Stroke = new SolidColorBrush(Colors.White),
StrokeThickness = size
};
Canvas.SetLeft(el, rnd.NextDouble() * 750 - 150);
Canvas.SetTop(el, -15);
((Canvas)this.RootVisual).Children.Add(el);
}
To make this work, you need to declare private Random rnd = new Random((int)DateTime.Now.Ticks);
at the beginning of the class. This will give us really random numbers.
Now press F5, and enjoy the animation!
What's next?
There's so much to go from here. One thing I've been planning to do is to use a XAML-less Silverlight control to alter the HTML DOM at runtime. And, I'm thinking about writing a Raycasting-engine, to be the heart of a Wolfenstein 3D clone. I even may do an article on that.
In the mean time, have fun with Silverlight!
History
- 20-11-2008 - Initial upload.