Light Up the Web with Silverlight by Jacek Ciereszko

Blog about programming in Silverlight

  Home  |   Contact  |   Syndication    |   Login
  15 Posts | 0 Stories | 22 Comments | 0 Trackbacks

News

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

Archives

Image Galleries

More About Me

News

Who was here

Wednesday, June 17, 2009 #

Hi, "Silverlight Count Down Control"  is now available in Silverlight 2.0! I did also some changes with tooltips. Read more on project's site ( http://silverlightgadgets.codeplex.com/ )


Live demo (Silverlight 2.0) : http://wpierdalaj.pl/SWG/SilverlightCountDown/Run/SilverlightCountDownTimerExampleTestPage.html

More info about control:
http://geekswithblogs.net/SilverBlog/archive/2009/04/27/silverlightcountdowncontrol.aspx

Sunday, May 31, 2009 #

“Out Of Browser (OOB)” for Silverlight is a possibility to install RIA application on local computer and run it without web browser or even internet connection (occasionally connected applications). That’s why we have in title abbreviation RDA (Rich Desktop Application).

In this article I would like to present how it’s working and how to implement it in our application. It also contains demos, descriptions and a lot of images.

Demo

First we start with already working application, created for MIX09 conference. To run it, please go to this link: Run DEMO - Chess. This demo require Silverlight 3.0 SDK installed – download.



To install game, we need to click „Install Chess Now” button or click right mouse button on application and choose install option. During installation we can decide where we would like to place shortcut to our game. We are not able to set where we would like to have all application’s files, but only shortcuts.

In Windows we can put shortcut on desktop or/and menu start. MAC’s user can drag and drop it  whenever they want. Of course in Windows we can also move installed shortcut later but we cannot change it during installation.


As you can see, installation process is a little supervised by Silverlight and not allow to modify too much.

“Out of browser” applications can work without connection to internet and synchronize data when this connection will be available. To store data we can use Isolated Storage memory, which after installation can contains 25MB of data without asking user. When we run application in browser, we can use only 1 MB without user permission. But in both situations, we are able to ask user and extend this limits.

To uninstall application, click right mouse button on application and choose uninstall option.

Let’s create our own OOB application

Let’s create simple Hello World application. This application will detect if it have access to the internet and if it work in browser or out of browser.

I. Simple installation
First step is a open Visual Studio and create new project “SilverlightApplication”. Then we open file „AppManifest.xaml” from “Properties” folder. Inside we should see commented code.


<Deployment.ApplicationIdentity>

     <ApplicationIdentity ShortName="Out of Browser Silverlight Application" Title="Window Title of your Silverlight Application">   

       <ApplicationIdentity.Blurb>Description of your Silverlight application</ApplicationIdentity.Blurb>


     </ApplicationIdentity>
</Deployment.ApplicationIdentity>

This commented code is responsible for turning on installation option and determine descriptions and used icons. After we uncomment this code we can run application and install it on our computer.

Before we do that, let’s add simple TextBlock in file MainPage.xaml to see where is our application and that it’s working.

<UserControl x:Class="SilverlightOOBApplication.MainPage"

    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="White">

        <TextBlock Text="Hello World" />

    </Grid>
</UserControl>
 

Now let’s run our HelloWorld. To install it, click right mouse button and choose „Install Out of Browser Silverlight … onto this computer„ .


Then choose place where would like to put shortcut to our application. We can install it on desktop or/and in start menu.

Now we should see HelloWorld in nice window. Our application work the same way like in browser but we don’t need connection to the internet and web browser.

II. Customize installation

First of all we can set parameters like “ShortName” used for example to name shortcut, “Title” as a local window’s title and “ApplicationIdentity.Blurb” as a description used for example in tooltips.

Let’s set this parameters. For example “ShortName” we will set to “Welcome App”, “Title” to “This is welcome application” and “ApplicationIdentity.Blurb” to “This is Hello World application and it makes nothing”.

AppManifest.xaml:
<Deployment.ApplicationIdentity>
 <ApplicationIdentity
      ShortName=" Welcome App "
      Title=" This is welcome application ">

    <ApplicationIdentity.Blurb>This is Hello World application and it makes nothing 

    </ApplicationIdentity.Blurb>

 </ApplicationIdentity>
</Deployment.ApplicationIdentity>
 
In addition user is able to add some icons. Let’s open AppManifest.xaml file and add information about them in xml, like in the code below. Images can be in png format and we need to set their “Build Action” properties to “Content”.

We need to create four images in different sizes (16x16, 32x32, 48x48, 128x128). They will be used as a icons on your desktop, icon in window or during the installation. Example of AppManifest.xaml can looks like this one:

<Deploymentxmlns="http://schemas.microsoft.com/client/2007/deployment"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >   
  <
Deployment.Parts>    </Deployment.Parts>
 
  <Deployment.ApplicationIdentity>

    <ApplicationIdentity ShortName="Welcome App"Title="This is welcome application. ">

     <ApplicationIdentity.Blurb>This is Hello World application and it makes nothing

     </ApplicationIdentity.Blurb>   

     <ApplicationIdentity.Icons>
      <IconSize="16x16">images/icons/user-16.png</Icon>
      <IconSize="32x32">images/icons/user-32.png</Icon>
      <IconSize="48x48">images/icons/user-48.png</Icon>
      <IconSize="128x128">images/icons/user-128.png</Icon>
     </ApplicationIdentity.Icons>
    </ApplicationIdentity>
 
  </Deployment.ApplicationIdentity>
</Deployment>
 
III. How to check if application run locally or in browser

In case we would like to know if application was run in browser or locally, we can check it using Startup event and read state of „Application.Current.RunningOffline” variable.

public partial class App : Application
{
        public App()
        {

            this.Startup += this.Application_Startup;

...
 }
 

        private void Application_Startup(object sender, StartupEventArgs e)

        {
            if (Application.Current.RunningOffline)
            {

                this.RootVisual = new OfflinePage();

            }
            else
            {

                this.RootVisual = new MainPage();

            }
        }
}

So variable „RunningOffline” provide information if program run out of browser or not, and like in code above, allows to choose different start page.

IV. How to check if internet connection is available

Method „NetworkInterface.GetIsNetworkAvailable()” shows actual state of application’s internet connection. It returns true if connection is available. We can also invoke method when internet connection state changes by using „NetworkChange.NetworkAddressChanged” event.

Let’s look at sample code below from ManPage.xaml.cs:

        public MainPage()
        {

            InitializeComponent();

            NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(OnNetworkChange);
        }
 

        void OnNetworkChange(object sender, EventArgs e)

        {
            if (NetworkInterface.GetIsNetworkAvailable())
            {               
                // connected
            }
            else
            {
                // not connected
            }
        }

Inside constructor we add method („OnNetworkChange”) to internet status’s event. When you have two connections on one PC and when you turn off one of them, application will invoke event “NetworkAddressChangedand methodNetworkInterface.GetIsNetworkAvailable()” will return still true. That’s why don’t use flags to monitor state of connection, always use „NetworkInterface.GetIsNetworkAvailable()” method.

On the other hand, connection to network where will be no Internet, is still a connection and method “GetIsNetworkAvailable()” will return true.

V. Application update

When you install application locally, you could probably want to update it when new version will be released. Silverlight make it automatically by downloading it and install with next application’s run. In addition, you can inform user about new version by using “ExecutionStateChanged” + “App.Current.ExecutionState” and displaying for example appropriate message.

App.xaml.cs:
public App()
        {
            ..
            this.ExecutionStateChanged += new EventHandler(App_ExecutionStateChanged);
            ..
        }

void App_ExecutionStateChanged(object sender, EventArgs e)

        {

            if (App.Current.ExecutionState == ExecutionStates.DetachedUpdatesAvailable)

            {

                MessageBox.Show "New application's version is available. Please restart program.");

            }
        }

ExecutionStateChanged” is invoked alwasy when application state changes. “ExecutionStates” contains also atributess like „Detached”, „DetachFailed”, „Detaching” or „RunningOnline”. We can use them to check if for example detaching was finished or is it working online.

As we can see, this type of configuration allows to work with instalation process easly and efficient.
Online Sample

Complete created application you can see here: Live DEMO (Silverlight 3.0 Beta 1)

Source code: link
Under the hood
Let’s look at OOB closely. All installed application works because they were saved locally on hard drive in user space with special given number. This number is used to locate the right application. Save programs are run thanks to sllauncher.exe which we can find in Silverlight folder (C:\Program Files\Microsoft Silverlight\3.0.40307.0\sllauncher.exe).


If we analyze shortcut to our application, we will find that it invoke sllauncher.exe with special parameters.

C:\Program Files\Microsoft Silverlight\<version>\sllauncher.exe <address.id>

Where “version” is a installed Silverlight version and “address.id” is a saved application’s www address with unique given number. Complete shortcut can looks like these:

„C:\Program Files\Microsoft Silverlight\3.0.40307.0\sllauncher.exe" localhost.4

or

“C:\Program Files\Microsoft Silverlight\3.0.40307.0\sllauncher.exe" www.jacekciereszko.pl.2

In Windows Vista we can find our saved (installed) application in folder

„C:\Users\<user name>\AppData\LocalLow\Microsoft\Silverlight\Offline\<address.id>”

There Silverlight store application’s files: xap, html, etc. In other operation systems this folder can be in different place but the true is that we don’t need them to work with Silverlight with OOB, so don’t be sad if you won’t find your repository.

Please, remember that your application always run in sandbox so after installation it not have any additional rights and it work the same way like in web browser. Using sandbox with Silverlight allows to install RIA application on local computer without administrator rights.

Installed application can detect if internet connection is available, work when this connection is not accessible and react when connection will work again. Thanks to this features, now we are able to create programs occasionally connected (Emissary) and synchronize gathered data once in a while.

Customization

First of all we can change appearance depends if application is installed or work in a browser (like in Chess demo, where in browser version we could only install application locally).

What should be also mentions is that in current version (Silverlight 3.0 Beta 1) we can only set window’s icon, title and position. Microsoft promised more options in next versions.

Debugger

My first problem with OOB was debugger who doesn’t work. Program runs outside of Visual Studio so debugger is not connected to our program. But, we have still “Attach to Process...” command and we can use it to debug programs. It is not what we would like to use, but it’s working.

Disadvantages

Few weeks ago I wanted to create application with „Out of Browser”, Silverlight Navigation and Silverlight Virtual Earth Map Control, but I found out some difficulties and eventually I realized that it won’t work. I had a problem with communication to VirtualEarth map (no support for HTML DOM). So before you start, better make simple “Proof Of Concept”.

Resources
  • Tim Heuera’s great screen cast showing how to create OOB application – link,
  • Chess game – link,
  • Ashish Shetty’s blog with some articles about “Out Of Browser” – link.

Regards,
Jacek Ciereszko



Monday, April 27, 2009 #

Few days ago I decided to create Silverlight control which will count down event’s time. Nothing complex but sometimes can be useful. Created counter allows to make configuration in code (C#), XAML or by binding, which mean it supports Model-View-ViewModel (MVVM). I also created a compiled version which can be configured from html code using initParams. More details and examples you can find on project’s site.


timerScreen.jpg

Project main site and source code: http://silverlightgadgets.codeplex.com/


Live demo (Silverlight 3.0 beta 1) : http://wpierdalaj.pl/SWG/SilverlightCountDown/Run/SilverlightCountDownTimerExampleTestPage.html

I looking forward for your feedback! I know that I have to do something with “look and feel” and downgrade this version to Silverlight 2.0. If you have any others issues, just please leave me a comment. Thank you!

Jacek Ciereszko


Polish version of this article:  http://jacekciereszko.pl/2009/04/silverlight-count-down-control-wasze.html


Thursday, December 04, 2008 #

Do you like install plug-in image for Silverlight 2.0? Do you think that user, who don’t know anything about Silverlight, will click it?



Usual the answer is NO!


What we should care is a user’s experience from first moments. If he disappoint on first install’s image, he probably won’t come back to our application.

What we can do about this?

We can customize installation process, so it will be more user-friendly and intuitive. We can give him information that everything is ok, that he should click installation button and nothing bad will happen!

To change installation process, we can create and show user our own “install plug-in” image. Let’s do this now!

For html files

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
   
<param name="source" value="ClientBin/SilverlightApplication1.xap" />
   
<param name="onerror" value="onSilverlightError" />
   
<param name="background" value="white" />
   
<param name="minRuntimeVersion" value="2.0.31005.0" />
   
<param name="autoUpgrade" value="true" />
   
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
       
<img src="ClientBin/InstallSL.png" alt="Get Microsoft Silverlight" style="border-style: none" />
   
</a>
</object>

To set our image, we should only change “src” value for <img tag and point it at our image. We can even modify entire html code, write nice information about application, video, links to others pages, etc.

For aspx files

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication1.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%">
 
<PluginNotInstalledTemplate>
     
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
         
<img src="ClientBin/InstallSL.png" alt="Get Microsoft Silverlight" style="border-style: none" />
     
</a>
 
</PluginNotInstalledTemplate>
</asp:Silverlight>

For ASP.NET (aspx) files we have to add parameter "PluginNotInstalledTemplate" and as a value insert html code. It can be, for example image with information about application or entire html code. In this example, I used the code from html example.

How to in easy way test our installation image

To test how our pre-installation html code looks like, we don’t need to uninstall every time Silverlight plug-in, we can use instead of it, additional features in Internet Explorer.

All you have to do is open “Tools” -> “Manage Add-ons” -> “Enable or Disable Add-ons”

Now find Silverlight plug-in and turn it on/off. Your application will restart automatically and pre-installer will appear.

My example

As a example I would like to show pre-installer image for my Solitaire Game.

Game looks like this:


When user don’t have plug-in to Silverlight, game looks like this:

But when we change pre-installer image, then game could look like this:


p.s. Polish version: http://jacekciereszko.pl/2008/11/obrazek-instalacyjny-silverlight-20.html

Best Regards,
Jacek Ciereszko


Monday, October 27, 2008 #

I just updated to RTW versiono one more article about Full Screen mode in Silverlight 2.0. This article describe how to add in few steps, full screen mode to our Silverlight applications.

Updated article you can find here: http://geekswithblogs.net/SilverBlog/archive/2008/06/10/full-screen-mode-in-silverlight-2.0-rtw-applications.aspx

Best Regards,
Jacek Ciereszko

Friday, October 17, 2008 #

Another day and new article updated to Silverlight 2.0 RTW.

This time I did my previously post about Isolated Storage Memory in Silverlight 2.0.
Updated article you can find here:   http://geekswithblogs.net/SilverBlog/archive/2008/06/15/isolated-storage-memory-in-silverlight-2.0-rtw.aspx

Best Regards,
Jacek Ciereszko

Thursday, October 16, 2008 #


I finally updated article and demo about connection html with Silverlight (both sides) to version Silverlight 2.0 RTW.
Updated article you can find here: http://geekswithblogs.net/SilverBlog/archive/2008/03/31/ping-pong-with-html-and-silverlight-2.0rtw.aspx

Best Regards,
Jacek Ciereszko

Thursday, September 11, 2008 #

Dave Gardner announced on this blog contest in which you can win 10 x Professional Visual Studio 2008 book. This is a free copy of Professional Visual Studio 2008.
All you have to do is Winners will be draw at random at the end of each month.  Every month 2 winners.

You can read more about this on http://www.professionalvisualstudio.com/blog/2008/09/11/win-a-free-copy-of-professional-visual-studio-2008

Sunday, June 15, 2008 #

In this article, I would like to describe Isolated Storage Memory in Silverlight 2.0 RTW. 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.

Make it easier

If you don't want to play with Streams, etc., you can simply use IsolatedStorageSettings class. This class works as a dictionary, where you have keys and values, so inserting and getting values is fairly easy.

Declaration

private IsolatedStorageSettings isolatedSettings = IsolatedStorageSettings.ApplicationSettings;

Save data

try
{
isolatedSettings
.Add("name", name);
}
catch (ArgumentException ex)
{
// error message
}

Read data

string name = String.Empty;
try
{
name
= (string)isolatedSettings["name"];
}
catch (System.Collections.Generic.KeyNotFoundException)
{
// error
name
= "anonymous";
}

Update data

isolatedSettings["name"] = "new name";

Delete data

isolatedSettings.Remove("name");

Clear all data

isolatedSettings.Clear();

Inserted data's count

isolatedSettings.Count();

Key's count

isolatedSettings.Keys;

Value's count

isolatedSettings.Values;

So as you can see, IsolatedStorageSettings makes our work easy and more pleasant, we have less code and work :)

How to increase amount of available data space (quota)?

We know that by default we have only 1 MB free space per application and usually, if we would like to cache some images or videos, it's not enough. To increase our space we need to ask user and if he agree, we can have even 8,589,934,592Gb space for our application (8,589,934,592Gb = long.MaxValue). :-)

To ask him, we need invoke method "IncreaseQuotaTo()", like in this example (we ask for 100MB):

private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
 
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
     
{
             Int64 sizeNeeded
= 1024 * 1024 * 100;
             
if (sizeNeeded > isf.AvailableFreeSpace)
             
{
                 Int64 newValue
= isf.Quota - isf.AvailableFreeSpace + sizeNeeded;
                 
if (isf.IncreaseQuotaTo(newValue))
                 
{
   
// save data
     
}
 
}
 
}
}


User's question:

We need ask him only once and if he agree, then we can save data whenever we want. Question looks like on picture above. Unfortunately, we can not modify text in question and this have to be invoked from event. It's mean that we can not ask user during  application's initialization
, only when he click something.

Attention IncreaseQuotaTo Localization Bug:
If your users have a Operating System (OS) other than in English version, you may not ask him question about increase quota and "IncreaseQuotaTo()" will automatically result with false. This happened for all user with no English version OS! This bug is well known for Microsoft and you can read more about it here: http://silverlight.net/forums/p/51485/135114.aspx


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 RTW. 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

    double _oldHeight, oldWidth;

  _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;

Constraints

I would like to add, that we have also few constraints. Namely, code above ( ..IsFullScreen != ..IsFullScreen) can be used only in event handler, invoked by user. So we can change application to full screen mode, only by clicking mouse on something or by pressing key on keyboard. This is because of security reasons. None of us, want to see advertisement, created in Silverlight, which will appear all the time and always in full screen mode ;)

Another constrains are keyboard and mouse functionalities in full screen mode, which are reduce to only:

  • arrows keys and space bar on keyboard
  • mouse buttons (even mouse wheel doesn't work!)
The last one is really "pain in my ass", because then applications written in Deep Zoom Composer in full screen mode, do not have zoom functionality. We can add keys to zoom but this is not the same fun like with mouse!

You can find more about constraints in MSDN link.

FIN

OK, now we have all that 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

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

Resize me and click on me!

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

Silverlight Solitaire

You can play it in small window, so nobody will see you in work :]

Resources

  • Mike Snows's blog link
  • Jeff Blankenburg's blog link
Polish version of this article
 
Sorry for my English. I hope you can understand it. :P
Jacek Ciereszko
polish blog: http://jacekciereszko.pl/

kick it on DotNetKicks.com