Click here to Skip to main content
6,595,444 members and growing! (20,424 online)
Email Password   helpLost your password?
Web Development » Silverlight » Controls     Beginner License: The Code Project Open License (CPOL)

Silverlight integrated into ASP.NET Ajax Control (Fifteen Puzzle Game)

By Ferreri Gabriele (Megasoft78)

Silverlight integrated into ASP.NET Ajax Control (Fifteen Puzzle Game)
C# (C# 2.0), Javascript, XML, CSS, HTML, XHTML, .NET (.NET 2.0), ASP.NET, Visual Studio (VS2005), XAML, WebForms, Ajax, Dev
Posted:26 May 2008
Updated:17 Jun 2008
Views:30,036
Bookmarked:55 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
12 votes for this article.
Popularity: 4.40 Rating: 4.08 out of 5

1
1 vote, 8.3%
2
3 votes, 25.0%
3

4
8 votes, 66.7%
5
Screenshot2.jpg




Introduction

Recently, I'm interested in a very amazing technology called Silverlight, and I'm trying to learn it because it's very powerful.

Actually Silverlight have 2 versions:

  • Silverlight 1.0 release

  • Silverlight 2.0 beta1

The difference between 1.0 and 2.0b1 is quite big:
  • Support .NET language on client side (C#, VB.NET,..) instead of JavaScript
  • A lot of controls from WPF
  • Subset of framework 3.5 (Linq, ...)

For a complete list of differences see here

Unfortunately, to easily use Silverlight 2.0 beta1 is necessary Framework 3.5 and Visual Studio 2008 personal or above.

My idea is to integrate a Silverlight control into an ASP.NET Ajax control, but it's seem quite difficult without Visual Studio 2008. For this reason I integrated a Silverlight 1.0 control into ASP.NET Ajax control using Visual Studio 2005.

Background

Normally when I start to learn a new technology I always try to implement a very simple example, but to make all more interesting, normally I implement a complete application or game.

When I was a child and there were no computers at home, I spent a bit of my free time playing with a game called Fifteen Puzzle. It's a very simple game but not absolutely easy to solve at the begin.

More details about it at this link

Then, I implemented it in Silverlight 1.0 integrated into a ASP.NET Ajax control.

Using the code

The solution is divided in the following projects:

  • Web Application : Containing the ASP.NET page that host the control
  • Class Library: Containing the control

In the web application we have just a ASP.NET web form that contains the control and a ScriptManager (the core of ASP.NET Ajax Framework).

In the control we have the following files:

  • FifteenPuzzle.cs : Server side control that extends ScriptControl;
  • FifteenPuzzle.js : JavaScript that contains the javascript class that implement the Silverlight control into an ASP.NET Ajax Control;
  • FifteenPuzzle.xaml : XAML that describe the fixed part of the control (The dynamic part is generated within JavaScript class);
  • Helper.js : JavaScript that contains same useful functions;
  • Silverlight.js : Standard JavaScript used to instantiated Silverlight control into a HTML div;

The class FifteenPuzzle extends ScriptControl (base class for all ASP.NET Ajax control on server side) and override 2 method:

  • GetScriptDescriptors : method used to pass parameters to the javascript class using JSON format:
    • xamlUrl: The url from the Resource used to generate the static part of xaml in Silverlight.
    • width, height: The size of control
    • imageUrl : use when the game is in puzzleRenderMode.Image
    • puzzleRenderMode : Enum used to define the 2 different mode to render the game (Number or Image)
  • GetScriptReferences : method used to pass the script url (I used GetWebResourceUrl because I embedded all scripts in the assembly)
    • Controls.Resources.FifteenPuzzle.js : Contains the javascript class of the Ajax control and extends Sys.UI.Control
    • Controls.Resources.Helper.js : Contains some utilities functions
    • Controls.Resources.Silverlight.js : Default Silverlight javascript to istantiate the plugin into a div
    protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
    {
        ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Controls.FifteenPuzzle", this.ClientID);
        descriptor.AddProperty("xamlUrl", this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.FifteenPuzzle.xaml"));
        descriptor.AddProperty("width", this.Width.ToString());
        descriptor.AddProperty("height", this.Height.ToString());
        descriptor.AddProperty("imageUrl", this.ImageUrl);
        descriptor.AddProperty("puzzleRenderMode", this.PuzzleRenderMode);

        yield return descriptor;
    }

    protected override IEnumerable<ScriptReference> GetScriptReferences()
    {
        List<ScriptReference> scripts = new List<ScriptReference>();

        ScriptReference scriptReference1 = new ScriptReference();
        scriptReference1.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.FifteenPuzzle.js");
        scripts.Add(scriptReference1);

        ScriptReference scriptReference2 = new ScriptReference();
        scriptReference2.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.Helper.js");
        scripts.Add(scriptReference2);

        ScriptReference scriptReference3 = new ScriptReference();
        scriptReference3.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.Silverlight.js");
        scripts.Add(scriptReference3);

        return scripts;
    }

  

The file Controls.Resources.FifteenPuzzle.js contains the javascript class Controls.FifteenPuzzle the encapsulate most of the logic.

The position of each piece of puzzle is contained into a multiple array 4x4. At the begin the array is initialized to the normal order and using javascript I render the pieces dynamically.

When the puzzleRenderMode is set to Number the following is the xaml generated for each piece:

    <Canvas Name="FifteenPuzzle1_Cell_15" Canvas.Left="219" Canvas.Top="370" 
    Canvas.ZIndex="3" Width="100" Height="100" Background="White" Cursor="Hand">
      <Rectangle Fill="#80000000" Width="98" Height="98" Canvas.Top="2" Canvas.Left="2" RadiusX="15" RadiusY="15">
      </Rectangle>
      <Rectangle Width="100" Height="100" Canvas.Top="0" Canvas.Left="0" RadiusX="15" RadiusY="15">
        <Rectangle.Fill><LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
          <GradientStop Offset="0" Color="Green"/>
          <GradientStop Offset="0.6" Color="Lime"/>
          </LinearGradientBrush>
        </Rectangle.Fill>
      </Rectangle><Rectangle Width="98" Height="98" Canvas.Top="1" Canvas.Left="1" RadiusX="14" RadiusY="14">
        <Rectangle.Fill>
          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0" Color="#FFFFFFFF"/>
            <GradientStop Offset="1" Color="#00000000"/>
          </LinearGradientBrush>
        </Rectangle.Fill>
      </Rectangle>
      <TextBlock Name="FifteenPuzzle1_TextBlock_3_2" Canvas.Left="0" Canvas.Top="5" 
    Canvas.ZIndex="1" FontFamily="Verdana" FontSize="70" Text="15" FontWeight="Bold" Cursor="Hand" />
    </Canvas>

When the puzzleRenderMode is set to Image the following is the xaml generated for each piece:

    <Image Name="FifteenPuzzle1_Cell_15" Canvas.Left="19" Canvas.Top="70" 
    Canvas.ZIndex="3" Width="400" Height="400" Cursor="Hand" Source="Resources/Photo.jpg">
      <Image.Clip>
        <RectangleGeometry Rect="200,300,100,100" RadiusX="15" RadiusY="15">
        </RectangleGeometry>
      </Image.Clip>
      <Image.RenderTransform>
        <TranslateTransform Name="FifteenPuzzle1_Cell_15_Transform" X="0" Y="0" />
      </Image.RenderTransform>
    </Image>

The algorithm used to shuffle the pieces is very easy and probably not really optimized, but seem work fine. I just create a random number between 1 and 15 and try if the move is available. The problem with this algorithm is that in theory it could take long time but for the "Law of large numbers" work fine. :)

The most important part of javascript class is the integration with Silverlight.

In the _renderControl function is called the Silverlight.createObject that instantiate the plugin attached to one html div. When the plugin is instantiated the event handler _onXamlLoaded is called and the dynamic part of xaml is rendered.

    _renderControl : function()
    {
        this.get_element().innerHTML = String.format("<div id='{0}_Content' style='width:{1};height:{2}'></div>", 
                            this.get_id(), this.get_width(), this.get_height());
            
        var hostId = String.format("{0}_Host", this.get_id());
        var bounds = Sys.UI.DomElement.getBounds(this._getContentElement());
            
        Silverlight.createObject(this.get_xamlUrl(), this._getContentElement(), hostId, 
        { width:bounds.width.toString(), height:bounds.height.toString(), version:'1.0' },
        { onError:null, onLoad:Function.createDelegate(this, this._onXamlLoaded) }, 
        null);
    },

    _onXamlLoaded : function(plugIn, userContext, rootElement)
    {
        this._plugIn = plugIn;
        this._rootElement = rootElement;
        
        this._renderNumbers();
        this._drawShuffleButton();
    },

 
I stored the references to plugin and rootElement in local javascript variable because I use it to generate dynamically the xaml using createFromXaml method. Infact when I generate the pieces I used the following code to attach it to the static part of xaml
    var numberElement = this._plugIn.content.createFromXaml(sb.toString(), false);
    this._rootElement.children.add(numberElement);

and the following code to get the element using the name and to attach the event handler on mouse click:

    var elementNumber = this._rootElement.findName(String.format("{0}_Cell_{1}", this.get_id(), n));
    elementNumber.AddEventListener("MouseLeftButtonDown", this._onNumberClick)

Points of Interest

I know that this is a very poor example compared with the possibility available with this framework, but it can be useful to start to understand the technology and to understand the possibility to integrate it into an existing ASP.NET application.

History

  • 26 May 2008 - First release.
  • 30 May 2008 - Added possibility to switch between Number and Image and improved article details.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ferreri Gabriele (Megasoft78)


Member
I'm an Italian Software Developer from about 10 years.
I worked a long time in south Italy (where I was born) and after 2 years in Milan and an year in UK, I'm working remotely from Italy as Senior ASP.NET C# Developer using ASP.NET Ajax technology for a UK company.

Visit my small project:
http://www.codeplex.com/VisualDB
Occupation: Software Developer (Senior)
Company: sparesFinder
Location: Italy Italy

Other popular Silverlight articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 11 of 11 (Total in Forum: 11) (Refresh)FirstPrevNext
GeneralSilverlight Puzzle PinmemberCigdem Patlak7:15 24 Jul '08  
GeneralRe: Silverlight Puzzle PinmemberFerreri Gabriele (Megasoft78)10:46 24 Jul '08  
GeneralRe: Silverlight Puzzle PinmemberCigdem Patlak8:30 4 Aug '08  
GeneralNice PinmemberAbhijit Jana1:42 11 Jun '08  
GeneralNice idea PinmemberFatGeek6:31 28 May '08  
AnswerRe: Nice idea PinmemberFerreri Gabriele (Megasoft78)11:51 28 May '08  
NewsRe: Nice idea PinmemberFerreri Gabriele (Megasoft78)12:02 30 May '08  
General3 points for at least having an online demo Pinmemberdefwebserver7:24 27 May '08  
AnswerRe: 3 points for at least having an online demo PinmemberFerreri Gabriele (Megasoft78)12:55 27 May '08  
GeneralNo code explanation PinmvpPete O'Hanlon1:26 27 May '08  
AnswerRe: No code explanation PinmemberFerreri Gabriele (Megasoft78)4:36 27 May '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 17 Jun 2008
Editor:
Copyright 2008 by Ferreri Gabriele (Megasoft78)
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project