Light Up the Web with Silverlight by Jacek Ciereszko

Blog about programming in Silverlight

  Home  |   Contact  |   Syndication    |   Login
  8 Posts | 0 Stories | 7 Comments | 0 Trackbacks

News

My post about Deep Zoom Composer was recommended by Scott Guthrie! :) (see here)

Archives

More About Me

Who was here

Sunday, June 15, 2008 #


In this article, I would like to describe Isolated Storage Memory in Silverlight 2.0. Isolated storage is a place on local disk, where applications have all access privileges to store their data. Default settings, give applications 1 MB space but this can be changed by administrator.
 

This memory space let application read files and create new, without special permissions. I used this feature, for example to store user settings (user name, application skins, etc.), local high scores for Silverlight game or as a flag in survey, to remember if user already voted today. It’s very useful and sooner or later you will use it ;)

Let’s dance

As an example, we will create simple demo, which will remember our name and will show it every time when we turn on application on our computer. 

First, let's add two controls to "enter name":
<TextBox Height="32" x:Name="EnterName" Width="192" Text="Enter your name here" TextWrapping="Wrap"/>
<Button Height="28" x:Name="SubmitButton" Width="106" Foreground="#FF313131" Content="Submit" Click="SubmitButton_Click">

and one control to "show entered name"
<TextBlock Height="91" x:Name="NameTextBlock" Width="284" TextWrapping="Wrap" >
   <Run x:Name="UserName" FontFamily="Comic Sans MS" FontSize="36" FontWeight="Bold" Text="" />
</TextBlock>

 Then, add methods to write and read name from file in Isolated Storage. These methods are invoked from SubmitButton_Click event and from Page.Loaded event. To do this, we need IsolatedStorageFile object 

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); 

which we will use to check if file with user name exist 

if (!isf.FileExists(“our_file.txt”)) 

and to create FileStream object 

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(“our_file.txt”, FileMode.Open, isf);

Now, all we have to do is use for example StreamReader and make all operation like with simple text file on desktop application. 

StreamReader sr = new StreamReader(isfs);
userName = sr.ReadToEnd();
sr.Close();

To save user's name in Isolated Storage, open file with different FileMode, for example

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(“our_file.txt”, FileMode.Create, isf);

 and instead of StreamReader, use StreamWriter

StreamWriter sw = new StreamWriter(isfs); 

All other parts of code for save method are similar to read parts.

Completed code for save method:
private void SaveUserName(string name)
{
     IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
     IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Create, isf);
     StreamWriter sw = new StreamWriter(isfs);
     try
     {
            sw.WriteLine(String.Format("{0}", name));
     }
     catch (Exception ee) { }
     finally
     {
            sw.Close();
            isfs.Close();
            isfs.Dispose();
            isf.Dispose();
            sw.Dispose();
      }

}
 

Completed code for read method:
private string ReadNameIfExist()
{
      string userName = String.Empty;
      IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
      if (!isf.FileExists(FILE_NAME))
            return userName;

      IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Open, isf);
      try
      {
            StreamReader sr = new StreamReader(isfs);
            userName = sr.ReadToEnd();
            sr.Close();
      }
      catch (Exception e) { }
      finally
      {
            isf.Dispose();
      }
      return userName;

}

Working example play demo - (remember to refresh web page F5)

Source code is below in “source code” section.


Where is that place

To find a place where exactly is our file with user's name, we have to use debugger in Visual Studio. Place breakpoint on isf variable and run application in debug mode.

 

 

Variable "m_AppFilePath" contain real path to Isolated Storage directory and file with user's name. This path is not easy to remember and it could looks like this

"C:\\Users\\ToJaUser\\AppData\\LocalLow\\Microsoft\\Silverlight\\is\\3tumcpvn.hf1\\wrelfaen.uut\\1\\s\\rtqyd4tgtuurqnzlqaf3otinrvcefdf4aeqlkxhw0dltde2t2uaaaeaa\\f"

Deleting isolated storage

If we don't want to keep any more data for Silverlight application in Isolated Storage, we can write program to clear this space or just click right button on any Silverlight application and choose "Silverlight Configuration"

 

 Then go to "Application Storage" tab.

 

 

In this window we can see all information about every Silverlight application which saved data on our disk. We have also opportunity to delete these files with only one click.
 

Source code

Working demo

Resources

  • MSDN System.IO.IsolatedStorage Namespace - link
  • “Switch On The Code” blog - linkit’s a little overdue but this was my first article about Isolated Storage Memory which I found few months ago.


kick it on DotNetKicks.com

 
Bests Regards ,
Jacek Ciereszko
also
http://jacekciereszko.pl – blog in polish


Tuesday, June 10, 2008 #

This time I would like to show, how to create full screen in Silverlight 2.0 Beta 2.0. Changing application to full screen using only "Application.Current.Host.Content.IsFullScreen" is nothing special because only web browser's window is changing. Our application, have still the same size like before switching to full screen state.

So how to resize application, so it will change simultaneously with web browser? Solution is very simple and all we have to do is use transformations.

Let's start with simple full screen. To switch to full screen mode we have to run only this code:

Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;

Now, we can add button to invoke code above.

Page.xaml:

<Button Content="Full Screen" Click="Button_Click" />

Page.xaml.cs:

private void Button_Click(object sender, RoutedEventArgs e)

{

 Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;

}

If you run your application now, you will see that full screen is already working and you can switch views by pushing the button.

So we have full screen but our application still have the same size.. Let's do something with that.

First we have to add ScaleTransform in Page.xaml code:

 <Grid.RenderTransform>
<
ScaleTransform ScaleX="1" ScaleY="1" x:Name="RootLayoutScaleTransform" />
 </Grid.RenderTransform>

and then some code in Page.xaml.cs. In constructor we have to remember original size

  _oldHeight = this.Height;
  _oldWidth = this.Width;

 and add some methods to work with resize and full screen events

Application.Current.Host.Content.Resized += new EventHandler(Content_Resized);
Application.Current.Host.Content.FullScreenChanged += new EventHandler(Content_Resized);

void Content_Resized(object sender, EventArgs e)
{
double currentWidth = Application.Current.Host.Content.ActualWidth;
double currentHeight = Application.Current.Host.Content.ActualHeight;

double uniformScaleAmount = Math.Min((currentWidth / _oldWidth), (currentHeight / _oldHeight));
RootLayoutScaleTransform.ScaleX = uniformScaleAmount;
RootLayoutScaleTransform.ScaleY = uniformScaleAmount;

}

FIN, our application is ready! It can resize with Web Browser's window and also when we turn on/off full screen mode.

But what happen if we use mouse and we have to read coordinates? Mouse’s coordinates are now not scaled, so all we have to do, is divide these points by our variable ”uniformScaleAmount”.

double currentY = e.GetPosition(null).Y / uniformScaleAmount;
double currentX = e.GetPosition(null).X / uniformScaleAmount;

OK, know we have all we can imagine. Our solution is simple and it can be easily applied to every application. It will be nice and very useful feature in every project.

Source code:   source code

mirror

Working demo:    play demo (Resize window and click on button!)

Resize me and click on me!

mirror

Working Example (Resize it or turn on Full Screen mode)

Silverlight Solitaire

Resources

  • Mike Snows's blog link
  • Jeff Blankenburg's blog link

 
Sorry for my English. I hope you can understand it.
Jacek Ciereszko
polish blog: http://jacekciereszko.pl/

kick it on DotNetKicks.com





Tuesday, June 03, 2008 #

I am glad to announce that we have winners of Central and Eastern Europe of “Win The Web and Discover Yourself!” contest in 2008. And the winners are:

Best Student Team:  HP Team from Poland (89 points)

  HP TEAM - Win The Web Contest


 Prize: 3 free tickets to TechEd in Barcelona !

 

Best Company: Team Carnation from Hungary (91 points)

(I don’t have image. Send me If you have any.)

Prize: engagement with the Microsoft Innovation Center team in Copenhagen!

 

About contest

Challenge took place almost two weeks ago (17-18 May) and consisted in creating one main application and three extra tasks, during only 24 hours of development with only a couple of snack breaks and no time for sleep. All participants started coding at 12:00 on Saturday and finished at 12:00 on Sunday.

The main task consisted in creating a web application for monitoring a fleet of lorries for a cargo forwarding company. The contestants were encouraged to take advantage of such cutting-edge Microsoft technologies as Silverlight, Virtual Earth, Windows Communication Foundation Services, LINQ to Database, live.com services, etc.

Winners in countries: 

Czech

  • 1st:  team Helios  
  • 2nd:  team Code4Fun    
  • 3rd:  team dotNETfellas  

Hungarian

  • 1st: Digitalmania (Student first prize)
  • 1st: Carnation (Best Company)
  • 2nd. Bounch of mice

Fair Play : Team Agysejt and Team Technik

Interware's special prize:  Northwind

ITSecure's special prize:  The Turing

 

Polish

  • 1st: HP Team (me and my team)
  • 2nd: UTP.NET TEAM
  • 3rd: Devenue

Ukrainian

  • 1st (student team): Best Future
  • 1st (company): SoftServe
  • 2nd : Ukrainian students
  • 3rd:  CTeam

And the reason why I am so happy about this is that I was one of participants and a member of them (HP TEAM) which won Polish and European part of contest. Members of HP TEAM: Michal Drozdowicz, Jakub Korczak and me, Jacek Ciereszko.

But because it’s not nice to boast I will just show our applications. ;)

Our Applications (Silverlight 2.0 Beta 1)

First we had to create entry application to participate in contest. We had a list of propositions and every team had to choose one and implement it. It was mandatory rule to participate in contest.

I and my team (HP TEAM) chose solitaire game. We create application using Silverlight and you can play this game here:


Solitaire

 

The main application and Task 2 are connected to one application and you can see it here:

Main Application

Before you say something wrong or you find a bug, please remember that all entrants had only 24 hours and we didn’t have time to write tests and implements all features.

More information

My polish blog: link

Summary

The reason why I wrote this post is because I wanted to thank to organizers. In this year they gave chance to participate also for people from other countries, like Poland. I hope that in next year this contest will be in all European countries and we all meet again.

 

See you on Tech-Ed 2008 (Barcelona, Spain),
Jacek Ciereszko

 


Monday, April 07, 2008 #

So now it's over. Conference is finished but we will all remember the best moments spent in last Saturday (04.07.2008). The pizza, gifts and knowledge about new things which we all learned is priceless and that's why I would like to thanks to all speakers and organizers.


I also added some pictures from conference:

1. Welcome


2. Maciej Szczepański and Paweł Leśnikowski in Test Driven Development (TDD) in practice.



3. Martin Kulov and "Debugging and Crash Dump Analysis of ASP.NET Web Sites".


4. Jarosław Kowalski with subject: "Introduction to Entity Framework".



5. Dino Esposito and "Understanding Goals and Features of the ASP.NET MVC Framework".





6. A little competition



7. Marcin Celej, Michał Brzozowski and ".NET Developer Toolbox A.D. 2008". (I don't have picture, sorry).

8. Organizers


Organizers: Daniel Arak, Michał Grzegorzewski, Paweł Potasiński, Marek Byszewski, Aneta Sidorowicz, Michał Chaniewski, Joanna Grzywna, Szymon Kobalczyk, Paweł Łukasik, Łukasz Olbromski, Łukasz Gąsior, Marcin Samelak, Maciek Paczewski, Karol Stilger and Justyna Spychała. Thank you very much!

 

9. Me and Dino :D

10.  Martin Kulov, Paweł Potasiński, Dino Esposito, Paweł Leśnikowski and me.


 

If you can read polish texts you can find more on http://jacekciereszko.pl/2008/04/moje-wraenia-po-c2c-materiay.html

Jacek Ciereszko


Thursday, April 03, 2008 #

In my next article I would like to present simple demo with Button placed in another Button and so forth.

First I tried to show ToolTip inside button from another Button's ToolTip but It doesn't work, only one tooltip can be displaied at one time.

So I put many buttons inside others. I added also tooltip with video and buton inside Tooltip. Everything is showed on demo.


Demo:



Source Code:  
Source Code (ContentInSL.zip)

Polish mirror of this article: http://jacekciereszko.pl/2008/04/button-jako-content-tooltipa-z-buttona.html

Jacek Ciereszko

Monday, March 31, 2008 #

I created demo that show how to connect Silverlight 2.0 with code html. This demo is like a game ping-pong, but it is not really game because you not suppose to play but learn Silverlight 2.0 !

My demo from my polish blog (in polish) http://jacekciereszko.pl/2008/04/ping-pong-with-html-and-silverlight-20.html

Source code:  http://pizza-warszawa.hostedwindows.pl/blog_resources/HtmlPingPong.zip

Demo

Jacek Ciereszko


Tuesday, March 25, 2008 #

Because I can't modify my html code on this blog I temporary move to http://jacekciereszko.pl/

In this article I would like to present simple application with MultiScaleImage control and generated images from Deep Zoom Composer application. I hope my English is enough to understand this text but just in case I will put a lot of pictures. I will show you how to create application with very deep zoom and put it inside Silverlight 2.0.

First we have to generate project with images, therefore we have to download Deep Zoom Composer application. This process has 3 steps:

  1. "Add Image…"

    Create new project ("File"->"New Project…") and import images ("Add Image…"). Choose for example 3 images, not too much. Please, check if they are not too big (greater than 2MB).

  2. "Compose"

    Now we go to another step by clicking "Compose" button in the top of the screen.

    Then, drag and drop images. Take first one, resize and fit it to the screen.



    Zoom in image and place another one.

    And do the same to others pictures. Zoom it, and put image in that place.

  3. "Export"

    OK, so we created images, let's "Export" this to Visual Studio.

    All we have to do, is set path for our project ("Export Location"), add Name and choose if it will be exported to "deep image collection" (it generate more files and from my view it work slower).

    After this step we should have in our output something like this:


We need only folder with images and file "info.bin", in my example this is folder "deepzoomcomposerek".

OK, we have images from Deep Zoom Composer application. Let's put this to Silverlight 2.0 (If you haven't installed Silverlight Tools Beta 1 for Visual Studio 2008, you can download it here).

First, create new project in Visual Studio 2008.


I chose option "Generate an HTML test page..." because I don't need html files to add javascript to web page, I will create single silverlight project and use key down.

Now, build your project and copy folder with images (in my code this is "deepzoomcomposerek") from output (Deep Zoom Composer) to ClientBin folder (Visual Studio project). You should see something like this:

In Page.xaml file add code:

<UserControl x:Class="DeepZoomComposer.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="1024" Height="768">
    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage Canvas.Top="10" Canvas.Left="10"
     
  x:Name="wg_net_ZoomObject" ViewportWidth="1.0" Height="768"
        Width="1024" Source="/deepzoomcomposerek/info.bin" />
    </Grid>
</UserControl>

Now you should be able to run your project and see your images.

Let’s add mouse and key control. We have to add events to MultiScaleImage in Page.xaml:

<UserControl x:Class="DeepZoomComposer.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    KeyDown="UserControl_KeyDown" MouseLeave="UserControl_MouseLeave"
    Width="1024" Height="768">

    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage Canvas.Top="10" Canvas.Left="10" x:Name="wg_net_ZoomObject"
            ViewportWidth
="1.0"  Height="768" Width="1024" Source="/deepzoomcomposerek/info.bin" 

             MouseLeftButtonDown="wg_net_ZoomObject_MouseLeftButtonDown"
            
MouseLeftButtonUp="wg_net_ZoomObject_MouseLeftButtonUp"

                 MouseMove="wg_net_ZoomObject_MouseMove"   />

    </Grid>
</UserControl>

and implementation to Page.cs:

bool dragInProgress = false;  //global variables
Point dragOffset;
Point currentPosition;


      private void UserControl_KeyDown(object sender, KeyEventArgs e)
      {
            Point p = wg_net_ZoomObject.ElementToLogicalPoint(new Point((wg_net_ZoomObject.Width / 2),
((wg_net_ZoomObject.Width / wg_net_ZoomObject.AspectRatio) / 2)));
            switch (e.Key)
            {
                case Key.Q:
                    wg_net_ZoomObject.ZoomAboutLogicalPoint(1.1, p.X, p.Y);
                    break;
                case Key.E:
                    wg_net_ZoomObject.ZoomAboutLogicalPoint(0.9, p.X, p.Y);
                    break;
                case Key.Left:
                case Key.A:
                    wg_net_ZoomObject.ViewportOrigin =
                        new Point(wg_net_ZoomObject.ViewportOrigin.X - 0.1,
                        wg_net_ZoomObject.ViewportOrigin.Y);
                    break;
                case Key.Right:
                case Key.D:
                    wg_net_ZoomObject.ViewportOrigin =
                        new Point(wg_net_ZoomObject.ViewportOrigin.X + 0.1,
                        wg_net_ZoomObject.ViewportOrigin.Y);
                    break;
                case Key.Up:
                case Key.W:
                    wg_net_ZoomObject.ViewportOrigin = new Point(wg_net_ZoomObject.ViewportOrigin.X,
                      wg_net_ZoomObject.ViewportOrigin.Y - 0.1);
                    break;
                case Key.Down:
                case Key.S:
                    wg_net_ZoomObject.ViewportOrigin = new Point(wg_net_ZoomObject.ViewportOrigin.X,
                      wg_net_ZoomObject.ViewportOrigin.Y + 0.1);
                    break;
                default:
                    break;
            }
        }

    private void UserControl_MouseLeave(object sender, MouseEventArgs e)
    {
            dragInProgress = false;
    }

    private void wg_net_ZoomObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
            dragInProgress = true;
            dragOffset = e.GetPosition(this);
            currentPosition = wg_net_ZoomObject.ViewportOrigin;
     }

    private void wg_net_ZoomObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
            dragInProgress = false;
    }

    private void wg_net_ZoomObject_MouseMove(object sender, MouseEventArgs e)
    {
            if (dragInProgress)
            {
                Point newOrigin = new Point();
                newOrigin.X = currentPosition.X -
                    (((e.GetPosition(wg_net_ZoomObject).X - dragOffset.X)
                    / wg_net_ZoomObject.ActualWidth) * wg_net_ZoomObject.ViewportWidth);
                newOrigin.Y = currentPosition.Y -
                    (((e.GetPosition(wg_net_ZoomObject).Y - dragOffset.Y)
                    / wg_net_ZoomObject.ActualHeight) * wg_net_ZoomObject.ViewportWidth);
                wg_net_ZoomObject.ViewportOrigin = newOrigin;
           
}
     }
 
Now you can run application and “deep zoom” in your images. As you can see in code, you can zoom in/zoom out your images with Q and E or move them with W, S, A, D and arrows.

Very good resources:

Source code:

  • mirror 1 (if it stop working, please let me know)

Working demo:

FIN

I hope you enjoy this article, it was my first in English and I think the last one on this blog. There is a plenty good blogs in English and I don’t want to just copy them. So if you have any question about articles wrote in polish, send me email and I will try to help you.

 

Jacek Ciereszko

polish blog: http://jacekciereszko.pl/