Tuesday, July 29, 2008

Some Lesser known things in Silverlight

[ Updated for Silverlight 2]

Here are some of them.......


1. EnableFrameRateCounter :
Wander what fps (Frames per Second) is you silverlight application running? Set EnableFrameRateCounter="true" in your aspx page.
The default maximum value is 60

this is what is shows in my browser. 19.74 is actual and 60 is max set value.




You can set MaxFrameRate there in that tag too. The Actual fps will depend with processor speed and how busy it is.


2. EnableRedrawRegions:
This is sometimes helpful when debugging. Setting it true will show when Silverlight redraws any region. Here I what I got when animating a circle.




3. PluginNotInstalledTemplate: This is useful when you want to do something when Silverlight plugin is not installed in users browser. This is how to do it

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TicTacToe.xap" MinimumVersion="2.0.30523"
Width="100%" Height="100%">
<PluginNotInstalledTemplate>
Write something to show if plugin not installed
</PluginNotInstalledTemplate>
</asp:Silverlight>

4. SplashScreen: Whenever we start a silverlight application the silverlight control provides a default splash screen while the xap file is loading. It is pretty good but still sometimes we need to add our own splash screen. Here is the Silverlight tutorial that shows it step by step.

Here is a blog post that will help providing splash screen with asp:Silverlight tag.


5. InitParameters: You can pass initialization variables with InitParameters. here is a sample

InitParameters="BaseUrl=http://live.com,ResourceUrl=http://www.microsoft.com">

and now from App.Xaml.cs file

private void Application_Startup(object sender, StartupEventArgs e)
{
string baseUrl = e.InitParams["BaseUrl"];
string reasourceUrl = e.InitParams["ResourceUrl"];
this.RootVisual = new Page();

}
You can pass the parameters in the constructor of Page class.

6. Read Query Strings: Add System.Windows.Browser namespace where you want to access query string.

if(HtmlPage.Document.QueryString.Keys.Contains("Name"))
{
string name = HtmlPage.Document.QueryString["Name"];
}

Url- http://SampleDomain/SamplePage.aspx?Name=Tanmoy

7. Famous Firefox nested DIV problem: Strictly speaking this is not related to silverlight. Still you might have faced this problem with firefox. Try to run the following in FF.

<div>
<div style="height: 100%;">
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TicTacToe.xap" MinimumVersion="2.0.30523"
Width="100%" Height="100%">
<PluginNotInstalledTemplate>
Write something to show if plugin not installed
</PluginNotInstalledTemplate>
</asp:Silverlight>
</div>
</div>


It will run in IE but not in FF. Remove the upper DIV and it will run properly. One work around is to set height=100% to the upper DIV. This problem is because FF deals DIV differently.

8. What the ifame is doing here?: If you see the html object code for silverlight page you will see one iframe after the object tag.
<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

The reason behind this iframe is stated in the documentation like the following

The presence of an IFrame prevents the Safari browser from caching the page. Safari caching prevents the Silverlight plug-in from reloading when the user navigates back to a previously-visited Silverlight page.

9. How to open .xap file: I guess you already know it but if you don't it is one coolest thing. XAP is a binary format but it is actually a .zip file renamed to .xap. So you can open it with WinZip or any other .zip file opener. It has one AppManifest.xaml file inside that defines the entry points and other assembly you are using. It also will have DLLs and optionally any resources you need to be loaded with the xap.

10. Relative positioning: It is possible to position the elements inside the Silverlight component relatively. For this you have to use Grid or StackPanel. I am showing it with a code.

<Grid x:Name="LayoutRoot" Background="Gray" ShowGridLines="True" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300" Height="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="50" />
<RowDefinition Height="2*"/>
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="2" Grid.Row="2" Height="40" Width="30" Fill="Blue" />
</Grid>

First the ShowGridLines="True". It is very useful when you are experimenting with Grids. It shows the outlines of your Grid with dotted lines.

Now here is the output I got


Now here is explanation.

Total width is 300 px and it is distributed with 4 columns in 1:2:3:1 ratio.

Now coming back to rows. There are 4 rows sharing 300px height. But one of them is occupying 50px. Now the height of the 3rd row is set to auto. That means it will take the height of its child element. That is the blue rectangle. Rest of the height available will be distributed with other two rows with 2:1 ratio.

I have been writing this post for quite a long time. Been busy with other tasks too. In anything you want to ask please leave a comment.

Friday, July 18, 2008

Why I Shifted My Blog

I have been using Wordpress.com for my blogs for quite a long time. I did not have any problem until recenly. Now as I am building a blog for Silverlight I first chosen Wordpress. The problem I faced was I can not display my application in my blog using javascript or even iframe. That was really annoying as I need at least iframe support. I searched their forum and it clearly been said iframe support is a distant dream. After continuing for some days I finally changed it to "old friend" blogger.com. Now I changed the design a bit. I am not a designer and this blog might not look very nice to you :).Still it is more flexible than that is in Wordpress and I will try to continue this here.
Thanks

Mahjong! My favorite game

[ Updated for Silverlight 2]

Mahjong has been my favorite game since the days I started using Linux (SUSE 10.2). I just tried and made "Something" (Play it full screen. F11). So I can play my favorite game in my off time. Of course it was again with Silverlight. Now here is the explanation and logic used to make this game.






Design

Page:

Page has 4 grids each with 15x9 dimension. So ultimately it gives the impression of a 3D stack. Each cell (total 15x9x4 cells) can be filled with a tile or left empty. The grids are been filled with tiles such a way it looks like a nice structure. In this structure 4th grid (I am calling as 4th rank) is empty. There are total 144 tiles. There are 12 types of tiles.

Tiles:

Each Tile is a user control. It has two canvases with rounded corner rectangles to make the nice 3D effect.

On the top canvas there are two rectangles. One for holding the tile image, another one to have mouse over effect.(Yellow one).

Each tile has 4 types of animations associated with it. (ClickAnimation, ClickOutAnimation, MouseOverAnimation, NotMatch). Click out animation will happen if user clicks the same tile twice. Not mach animation will happen when user tries to match wrong set of tiles.

Each tile has one TileNumber that determines the image to be put in the tile and it also helps in finding match.

Algorithm and code

Tile:

Each tile is having four variables associated with it.

TileNumber- Used to find match.

TilePosition- Gives rank, row and column in a 3 dimensional structure.

ParentPage- A reference to the Page class so it can call its methods.

IsClicked- Tells if the tile has already been clicked

Before starting any animation it will call its ParentPage method CheckIfFree to see if the tile is free.

On click of the tile after confirming it is free It will again call another parent page method TileClicked. This method will try to match this current tile with the previous tile clicked. If it matches It will destroy two tiles or it will show the NotMatch animation.

The constructor of this user control takes a random number from Page and set the tile image accordingly.

Main Page and logic:

In the Page there are 4 grids (4th one is empty in this tile structure I am now using).

First I am making the look of the board with a 3 dimensional array. Each element of that array represents empty or occupied state in boolean.

After making the grid structure I am adding tiles which are marked occupied.

In making the tiles for each tile GetTileNumber method returns one random number between 0 to 11 and it returns such a way that every number will be for 12 times making total 144 tiles.

This is the tile number used generally and I am also using for my game.

int[] TileTypeCount;
TileTypeCount = new int[12];

private int GetTileNumber()
{
int tileNo;
do
{
tileNo = rnd.Next(12);
} while (TileTypeCount[tileNo] >= 12);

TileTypeCount[tileNo]++;
return tileNo;
}


Filling tiles for the fast grid. Lowest level


// for set 1 rank 0
for (int row = MaxRow - 1; row >= 0; row--)
{
for (int col = 0; col < MaxCol; col++)
{
if (TileGridStructure[0, row, col]) continue;
TileStructure tile = new TileStructure(GetTileNumber(), this, new Position(0, row, col));
Grid.SetRow(tile, row);
Grid.SetColumn(tile, col);
Set1.Children.Add(tile);
TileCollection[0, row, col] = tile;
}
}



TileGridStructure tells if this place is to be filled with a tile or not.

Here you will find the complete source code.

Bye for now. Please leave a comment if you have any doubt or correction.

Experimenting with DeepZoom

A new feature in silverlight is DeepZoom. Its extreamly popular in the Silverlight community and looks kool. I never touched it before. Today I installed DeepZoom Composer and started building "Something". It was easier than I thought. I used 50 images (Hi-resolution upto 7432 X 4168 ). All collected from wikipedia featured pictures to avoid licencing issues. I shaped it over like a G. It goes well. But I was trying to make something like DeepZoomObama. Last I saw the blog that describes Making of DeepZoomObama project. All that is need to make a mosaic with lots of images. I collected more (more than 350) Images from wikipedia and started building it. It took only around 2 to 3 hours to build this.



The software that used for this is andreamosaic and Silverlight Deep Zoom composer. Two softwares are extremely easy to use.

Eight Queen Code

[Updated for Silverlight 2]

I blogged previously about the N-Queen problem. Here I am going to explain how I did it.

The Board and the Queen
I used a StackPanel to hold the Board and the button. The board is a 8x 8 Grid. And empty at design time. Also have a event handler for the button Click.
The Queen is a user control having just a Image with a white Background.
Now adding one Canvas for each square and painting it with blackish or whitish gradient brush already created as a resource

Repeating this for 64 squares.


Canvas c = new Canvas();

if ((row + col) % 2 == 0)

{

c.Background = (LinearGradientBrush)Resources["BlackBrush"];

}

else

{

c.Background = (LinearGradientBrush)Resources["WhiteBrush"];

}

Also having a blue hidden rectangle in each square that shows up when that square is being traversed and creates a nice animation. Also having a global variable for storing the squares and blue rectangles as we need them later.

For adding and removing the Queen I am using this code.

Sqare[row, col].Children.Add(new Queen());

Sqare[row, col].Children.RemoveAt(0);

The Animation

The animation for the blue rectangle is like the following.


<Storyboard x:Name="AnimSquare" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2">

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00">

<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

<SplineDoubleKeyFrame KeyTime="00:00:00.1" Value="1"/>

<SplineDoubleKeyFrame KeyTime="00:00:00.13" Value="0"/>

</DoubleAnimationUsingKeyFrames>

</Storyboard>


See there is no target name defined for the storyboard as we will be applying different square (The blue rectangle over the square exactly) as target.


AnimSquare.Stop();

Storyboard.SetTarget(AnimSquare, SquareMask[Grow, Gcol]);

AnimSquare.Begin();

The Algorithm

The algorithm is as follows.

As there will be 8 Queens for 8 rows there will be one at each row.

Start from the left top square.

Put a Queen if that does not captured by other queens.

Jump to the next row and try it for 8 squares in that row.

If unsuccessful then go to previous row and remove the previous Queen placed there and try another square that have not been tried for that row.

If that also unsuccessful go to lower rows until you find a new square to put the queen in that row.

This can be achieved with a recursion.


private void PlaceQueen(int row, int col)

{

if (row == NoOFQueen) return; //Get out of recursion

CheckedCol[row] = col;

if (IsSafe(row, col))

{

if (!flag)

{

PutQueen(row, col);

row++;

col = 0;

}

else

{

CheckedCol[row] = 0;

row--;

RemoveQueen(row, CheckedCol[row]);

col = CheckedCol[row] + 1;

}

}

else

{

if (col == (NoOFQueen - 1)) // No where to place queen in the row

{

CheckedCol[row] = 0;

row--;

RemoveQueen(row, CheckedCol[row]);

}

else

{

col++;

}

}

//Grow = row; Gcol = col;

PlaceQueen(row, col);

}

Now the methods used here are self explanatory and simple. There is only one tricky part in this recursion. That is the boolean flag. It keeps the track if the queen from the last column has been removed. So next there wont be any queen placed on that column even if the square is safe. It will go farther one level down and so. The flag is set false whenever a new queen is placed on the board.

There I did a little change in this method. Instead of calling the same method from PlaceQueen it has been called from a Tick event of a timer to enable animation. (see the commented Grow and Gcol. G for global ).

This version of my program is still yet needs optimization and some code cleanup. It does not check if something unexpected happens. It doesnt even have a safecounter for getting out of recursion in case 8 Queens can not be placed at all.

Here is the demo.

And you can download the complete source from here.

for any clarification or modification please leave a comment.

N-Queen Problem using Backtrack Recursion

[ Updated for Silverlight 2 ]

Hi,
For last two days I am trying to build a Silverlight Program that will solve n-queen (here I am using 8 ) problem and show it step by step to the user. After messing up with the logic finally managed to get it work. The algorithm still needs some improvements. I have uploaded the application in live streaming .





Those don't know about the 8-Queen Puzzle it is to place 8 queens in a chess board so no queen can capture others.

Here is the complete code for it. I will look up the code and clean it. I will explain it in my next post. For now I am listening to Celine Dion. There are lots of things happening today to make me happy :)

Beta 1 is dead

[ Beta 2 is dead too. This post is invalid after Silverlight 2 released ]

As we see with the linux development community there are some who like beta versions (me one of them). In Fedora download site I got it saying "Did someone say... beta?"

The main thing is there are some unknown or unintentional features (Bugs?!) that we use in betas to get our programs work. These hacks work great until the feature has been changed or removed :(. In the Code complete Steve Mcconnell warns us not to use them.

Anyway the code we have been building in Silverlight 2 beta 1 refused to work in beta 2. After some search and try error it did run but some parts needed complete rewrite.

Still I say its better to modify your application for beta 2 in case you did not do it yet. Here is why......

1. The user who is about to see it is more likely having latest plugin that is beta 2 and your beta 1 will refuse to work.

2. With time goes there will not be much help available for beta 1. Forum people will say UPGRADE.

3. There has been lots of modification from beta 1 to beta 2 but it is expected not to change much from beta 2 to final version.

So how to upgrade........

1. Uninstall your previous Silverlight stuffs. VS 2008 tool, Blend, everything.

2. Install new versions of those tools Silverlight tools beta 2. Expression Blend 2.5 June Preview.

3. Open your Visual Studio solution file. It will ask you to upgrade with beta 2.

4. Build your program. I will come to this point later.

5. After successfully build check the test aspx and html page of the website. There change type="application/x-silverlight-2-b2" in html and in aspx replace version attribute with MinimumVersion="2.0.30523". Also in the install silverlight link will be changed from http://go2.microsoft.com/fwlink/?LinkId=108182 to http://go2.microsoft.com/fwlink/?LinkID=115261.

What if my build failed...........

There are huge modifications from beta 1 to beta 2. So your old application might need to modify.

1. See the change list from here.

2. In my case the problem was with WebClient class. Because WebClient has been moved to System.Net.dll.

3. Another problem you might face is with event bubbling. Jesse Liberty has a great post explaning it. Basically you wont be able to catch mouse or keyboard events for controls because they themselves handle it. It has been done to maintain similarity between WPF and Silverlight. There are some workarounds if you really want to handle those events yourself. First Modify the template of your control or build a custom control deriving from the control you want to modify.

What if all of them don't work for me.........

Forums :)

My Experience with Silverlight

I have started my programming life with Silverlight. So it might be that I see it from a different view than some others already been in animation and programming.
        The thrill that has been with it was its limited spread at that time. So there were hardly any people whom you can ask for help. The online rapid growing comunity has been a great comfort and still is. Some people really did excellent things that keep on impressing me.
        The first task was a presentation kind of thing to be done with Silverlight 1.0. The animations and design are done by Pallavi and I know only little about designing.
        As I am going through it and trying to explore more of it there are so many things to learn. After a bit break with Silverlight after 1.0 I am now back and working with Silverlight.

        I am not a writer and so I better stop now. I will try to keep on posting here some tips and tricks and workarounds that might help you save the time I have wasted to learn them.

Thanks all for visiting my blog. I will try to keep it alive.