XAML Playground
about XAML and other Amenities

SilverlightPlayground is moving to XAMLPlayground

2012-07-01T16:00:00+01:00 by codeblock

In the day I got my MVP for the 6th time in a row (the fifth under the Silverlight expertise), I would like to make it official, a change that someone can have miss. If you watch at the page header of this site, the title is now "XAML Playground", just to be witness of a biggest change that has happened in the previous months.

Many of you are aware that, after the technology shift predicted by Bob Muglia during October 2010, lot of things have changed in the horizon of the technology from which this site has born. Silverlight today is not only Silverlight but a set of technologies now have their roots starting from its seed. We have Silverlight on the Windows Phone, we have Silverlight on the Embedded systems and, mostly important we have Silverlight on Windows 8 under the name of XAML.

And it is exactly reflecting the name change that happened in Windows 8, that I decided to slightly change the title from "Silverlight" to "XAML".

The reason of this change is probably clear. I strongly believe that the power of Silverlight is now part of something much more bigger and it has a bright future. All these technologies have a sole common denominator that is XAML.

So, as it happened since the start of this year, expect in the future, a number of posts on Silverlight in the various flavour, for the Web, for Windows Phone, for Metro UI and probably also for Windows (ops... WPF). 

From now please be aware you can use three domains to reach this site:

http://www.silverlightplayground.org

http://www.xamlplayground.org

http://www.metroplayground.org

So definitely, it is all about XAML

Categories:   General | News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Download Silverlight & WP7 RFB Library

2012-03-07T00:34:58+01:00 by codeblock

Senza-titolo-1Today I decided to release the libraries I wrote to handle the VNC connection, implementing the Remote Framebuffer protocol, as an Open Source project under the Creative Common license. You can download the library from this page:

http://xamlplayground.org/page/Silverlight-WP7-RFB.aspx

During last weeks I've published a new version of SilverVNC, my popular client for Remote Framebuffer connections, that works on Windows Phone 7.5. After publishing the software as Open Source project on codeplex, for Silverlight 3.0 only, now the marketplace has also a mobile version that you can download for free or buy at these addresses:

Free Edition: view only
http://www.windowsphone.com/it-IT/apps/ef2ef5b9-192c-4d77-a684-c1e69bea24fa

Standard Edition: full control
http://www.windowsphone.com/it-IT/apps/e6c631e6-f6c4-49e5-98a9-d49eea8212cf

Enjoy the library.

Take a screenshot with Silverlight 5.0 and pInvoke

2012-02-28T00:36:14+01:00 by codeblock

PInvoke is a new entry in Silverlight 5.0 runtime. For the one that are not aware of what is pInvoke I will say it stands for "Platform Invoke". It is a set of classess and attributes that allows the Silverlight runtime to access the low-level Win32 API of Windows Operating System.

After Silverlight 4.0 brought COM interop in Silverlight, the team decided to accomplish the last step and integrate also pInvoke. As you understand, it is only restricted to Windows OS, but is some scenario it may be a very useful thing to cross the subtle line from "can't do" to "can do". Wether you have to detect USB keys, interact with devices and so on, pInvoke require you to directly access the API preparing the mapping to the OS funzions and handling unmanaged resources.

As a littel sample I ported an old example to Silverlight. The code below implements a simple funzion that is able to take a screenshot of the desktop.

   1: public static class ScreenCapture
   2: {       
   3:   public static WriteableBitmap GetDesktopImage()
   4:   {
   5:       WriteableBitmap bmap = null;
   6:  
   7:       // initialize unmanager pointers
   8:       IntPtr hDC = IntPtr.Zero,
   9:              hMemDC = IntPtr.Zero,
  10:              desktop = IntPtr.Zero;
  11:  
  12:       try
  13:       {
  14:           // get a reference to desktop
  15:           desktop = User32.GetDesktopWindow();
  16:           // get an handle to Device Context
  17:           hDC = User32.GetDC(desktop);
  18:           // create a new Device Context in memory
  19:           hMemDC = Gdi32.CreateCompatibleDC(hDC);
  20:  
  21:           // read size of desktop window
  22:           Size size = new Size
  23:           {
  24:               Width = User32.GetSystemMetrics(Gdi32.SM_CXSCREEN),
  25:               Height = User32.GetSystemMetrics(Gdi32.SM_CYSCREEN)
  26:           };
  27:  
  28:           // create a bitmap compatible with desktop
  29:           IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hDC, size.Width, size.Height);
  30:  
  31:           if (hBitmap != IntPtr.Zero)
  32:           {
  33:               // select memory Device Context into the new bitmap
  34:               IntPtr hOld = (IntPtr)Gdi32.SelectObject(hMemDC, hBitmap);
  35:  
  36:               // copy the desktop to the memory handle
  37:               Gdi32.BitBlt(hMemDC, 0, 0, size.Width, size.Height, hDC, 0, 0, (int)TernaryRasterOperations.SRCCOPY);
  38:  
  39:               // select the memory Device Context into the bitmap
  40:               Gdi32.SelectObject(hMemDC, hOld);
  41:  
  42:               // initialize a bitmap info
  43:               BitmapInfo bi = new BitmapInfo 
  44:               { 
  45:                   biSize = Marshal.SizeOf(typeof (BitmapInfo)), 
  46:                   biWidth = size.Width, 
  47:                   biHeight = size.Height, 
  48:                   biPlanes = 1, 
  49:                   biBitCount = 32, 
  50:                   biCompression = 0, 
  51:                   biSizeImage = 0, 
  52:                   biXPelsPerMeter = 0, 
  53:                   biYPelsPerMeter = 0, 
  54:                   biClrUsed = 0, 
  55:                   biClrImportant = 0 
  56:               };
  57:  
  58:               // calculate byte size of the area
  59:               int dwBmpSize = ((size.Width * bi.biBitCount + 31) / 32) * 4 * size.Height;
  60:               byte[] data = new byte[dwBmpSize];
  61:  
  62:               // initialize a WriteableBitmap to output the result
  63:               bmap = new WriteableBitmap(size.Width, size.Height);
  64:  
  65:               // copy bitmap to byte array
  66:               Gdi32.GetDIBits(hMemDC, hBitmap, 0, (uint)size.Height, data, ref bi, 0);
  67:  
  68:               // compy byte array to WriteableBitmap
  69:               for (int i = 0; i < data.Length; i += 4)
  70:               {
  71:                   int y = size.Height - ((i / 4) / size.Width) - 1;
  72:                   int x = (i / 4) % size.Width;
  73:                   int pixel = data[i + 0] | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24);
  74:                   bmap.Pixels[y * size.Width + x] = pixel;
  75:               }
  76:           }
  77:       }
  78:       finally
  79:       {
  80:           // release unmanaged resources
  81:           if (hMemDC != IntPtr.Zero)
  82:               Gdi32.DeleteDC(hMemDC);
  83:           if (hDC != IntPtr.Zero)
  84:               User32.ReleaseDC(desktop, hDC);
  85:       }
  86:  
  87:       // return bitmap
  88:       return bmap;
  89:   }
  90: }

I wrote a number of comments inside the code example to try explain how it works, but in a few words it create a buffer in memory, take a reference to the desktop and copies it to the new area. Then finally it copy again the buffer to a byte array to allow managed code to access the captured image. It is copied to a WriteableBitmap and then returned to the caller.

To use the class you can simply call the static method and check for the result value and exceptions. The code automatically handles the unmanaged resources and is done to freed them before to exit.

   1: private void Button_Click(object sender, RoutedEventArgs e)
   2: {
   3:     Application.Current.MainWindow.Hide();
   4:  
   5:     Delay(1000,
   6:           () =>
   7:           {
   8:               try
   9:               {
  10:                   BitmapSource source = ScreenCapture.GetDesktopImage();
  11:  
  12:                   if (source != null)
  13:                       screenshot.Source = source;
  14:                   else
  15:                       MessageBox.Show("Impossibile completare la cattura!");
  16:               }
  17:               catch (Exception ex)
  18:               {
  19:                   MessageBox.Show(ex.Message);
  20:               }
  21:               finally
  22:               {
  23:                   Application.Current.MainWindow.Show();
  24:                   Application.Current.MainWindow.Activate();
  25:               }
  26:           });
  27: }
  28:  
  29: private void Delay(int timeout, Action action)
  30: {
  31:     Task task = new Task(
  32:         () =>
  33:         {
  34:             Thread.Sleep(timeout);
  35:  
  36:             Deployment.Current.Dispatcher.BeginInvoke(action);
  37:         });
  38:  
  39:     task.Start();
  40: }

This code minimizes the main window and then take a screenshot. Finally it reactivate the window and take it to the front. To compile this code you have to import a number of structures. The attached sample includes all the needed classes.

Download: XPG.PInvoke.zip

Categories:   Imaging | News
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

Silverlight 5.0 is here to stay!

2011-12-09T21:25:11+01:00 by codeblock

Silverlight-5Just a few minutes ago I’ve received the good news about the release of Silverlight 5.0 RTW. This is the release many of us are expecting for the end of the year as stated in some previous events. Silverlight 5.0 is a great big step forward on the development of business applications due to a number of improvements introduced in this technology.

These improvements involve full-trust, databinding, P/Invoke, Multiple windows and the introduction of the new 3d API based on XNA. For a complete list of the new features please visit Pete Brown’s blog where you can find an useful index with many examples linked.

By my side I’m planning to start writing about the new feature asap, waiting just the time of making my experiments to become usable examples. Probably I will post about 3d in the next days.

For now please let me make my compliments to the Silverlight team to be able to deliver this release despite of the continuous voices spreading arount about the death of this technology. Now we can say that Silverlight is a mature technology we can start use everywhere we need to easily deliver powerful business applications developed as fast as the light.

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlight 5.0: Custom Markup Extensions and Roles

2011-04-23T00:54:32+01:00 by codeblock

Starting from Silverlight 5.0 you can create custom Markup Extensions and this is an interesting feature to easily encapsulate some logic and make it easy to be applied to properties in the XAML markup. Until now you could only use a few extensions to apply resources (StaticResource), make databinding (Binding) and connect properties with parts of a template (TemplateBinding) but now, implementing a really simple interface you can build your own.

   1: public interface IMarkupExtension<out T> where T: class
   2: {
   3:     T ProvideValue(IServiceProvider serviceProvider);
   4: }

Using this interface you can specify the type to which the markup extension can be applied (the generic type T) but if you do not need a control about this type you can extend the MarkupExtension abstract class that is like you are extending IMarkupExtension<object>.

Inside the ProvideValue method there is the whole logic of the extension and using the IServiceProvider passed by the runtime you can get access to three services that let you get some informations about the markup where the extension is located.

IRootObjectProvider: provide a reference to the Root object of the VisualTree which the element is part of

IXamlTypeResolver : is able to resolve the name of the tags in the markup to the corresponding type.

IProvideValueTarget : gets a reference to the property and the elements which the markup extension is assigned

To retrieve an instance of this services you can use the GetService method on the IServiceProvider instance.

IProvideValueTarget target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));

In this example I wrote a RoleBinding extension that a developer can use to connect parts of the User Interface with a Validator class that is able to authorize the access to these parts using a set of custom rules. Let start writing the markup extension:

   1: using System;
   2: using System.Net;
   3: using System.Windows;
   4: using System.Windows.Controls;
   5: using System.Windows.Documents;
   6: using System.Windows.Ink;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.Windows.Markup;
  12: using System.Security.Principal;
  13: using System.Windows.Data;
  14: using System.Xaml;
  15: using System.ComponentModel;
  16: using System.Diagnostics;
  17: using System.Security;
  18: using System.Reflection;
  19: using System.Globalization;
  20:  
  21: namespace SLPG.MarkupExtensions
  22: {
  23:     public class RoleBindingExtension : MarkupExtension
  24:     {
  25:         /// <summary>
  26:         /// Gets or sets the name of the group.
  27:         /// </summary>
  28:         /// <value>
  29:         /// The name of the group.
  30:         /// </value>
  31:         public string GroupName { get; set; }
  32:         /// <summary>
  33:         /// Gets or sets the name of the feature.
  34:         /// </summary>
  35:         /// <value>
  36:         /// The name of the feature.
  37:         /// </value>
  38:         public string FeatureName { get; set; }
  39:         /// <summary>
  40:         /// Gets or sets the converter.
  41:         /// </summary>
  42:         /// <value>
  43:         /// The converter.
  44:         /// </value>
  45:         public IValueConverter Converter { get; set; }
  46:         /// <summary>
  47:         /// Gets or sets the converter parameter.
  48:         /// </summary>
  49:         /// <value>
  50:         /// The converter parameter.
  51:         /// </value>
  52:         public object ConverterParameter { get; set; }
  53:  
  54:         /// <summary>
  55:         /// Provides the value.
  56:         /// </summary>
  57:         /// <param name="serviceProvider">The service provider.</param>
  58:         /// <returns></returns>
  59:         public override object ProvideValue(IServiceProvider serviceProvider)
  60:         {
  61:             IProvideValueTarget target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
  62:  
  63:             bool isAuthorized = false;
  64:  
  65:             if (RoleManager.Current != null)
  66:                 isAuthorized = RoleManager.Current.Validator.Authorize(this.GroupName, this.FeatureName);
  67:             else
  68:                 isAuthorized = true;
  69:  
  70:             if (this.Converter != null)
  71:                 return this.MapToType(isAuthorized, target, this.Converter, this.ConverterParameter);
  72:  
  73:             return this.MapToType(isAuthorized, target);
  74:         }
  75:  
  76:         /// <summary>
  77:         /// Maps to type.
  78:         /// </summary>
  79:         /// <param name="isAuthorized">if set to <c>true</c> [is authorized].</param>
  80:         /// <param name="target">The target.</param>
  81:         /// <param name="converter">The converter.</param>
  82:         /// <param name="converterParameter">The converter parameter.</param>
  83:         /// <returns></returns>
  84:         private object MapToType(bool isAuthorized, IProvideValueTarget target, IValueConverter converter, object converterParameter)
  85:         {
  86:             PropertyInfo info = target.TargetProperty as PropertyInfo;
  87:  
  88:             if (info != null)
  89:                 return converter.Convert(isAuthorized, info.PropertyType, converterParameter, CultureInfo.CurrentCulture);
  90:  
  91:             return isAuthorized;
  92:         }
  93:  
  94:         /// <summary>
  95:         /// Maps to type.
  96:         /// </summary>
  97:         /// <param name="isAuthorized">if set to <c>true</c> [is authorized].</param>
  98:         /// <param name="target">The target.</param>
  99:         /// <returns></returns>
 100:         private object MapToType(bool isAuthorized, IProvideValueTarget target)
 101:         {
 102:             PropertyInfo info = target.TargetProperty as PropertyInfo;
 103:  
 104:             if (info != null)
 105:             {
 106:                 if (info.PropertyType == typeof(Visibility))
 107:                     return isAuthorized ? Visibility.Visible : Visibility.Collapsed;
 108:             }
 109:  
 110:             return isAuthorized;
 111:         }
 112:     }
 113: }

First of all I extend the MarkupExtension class. The core of the extension is the ProvideValue method. Inside this method I get a service that implements the IProvideValueTarget interface to retrieve informations about the property where the extension is applied to. In my case I need to know the type of the property because I have to map the boolean information (true means authorized, false means not authorized) to the property. For example if the target property is Visibility I map the true to Visible and false to Collapsed.

A markup extension can have a number of parameters. They are public properties exposed by the class. Differently from other existing extensions the custom extensions cannot have unnamed parameters. This is a choice of the Silverlight team I hope will change in future releases just to make extensions very close to the WPF ones. In my case the extension support these parameters:

GroupName and FeatureName: two strings that are used to select the feature and the category of feature the element is part. You can specify for example "Products" as GroupName and "Create" as feature. The values and their meaning are completely up to you. By default they are interpreted as role names where the two parts are joined by a dot: GroupName.FeatureName.

Converter and ConverterParameter: like the Binding extension it is a class that implements IValueConverter and a parameter passed to the class during the conversion. It is used to apply custom conversion to the boolean value that comes from the Validator. In the code provided with the post I use a converter to map the boolean to a Color (Red or Green). 

The extension rely on a Lifetime Object that contains the roles granted to the current user. In my example these roles are passed using the InitParams but please do not repeat this in a production environment because a malicious user can easily impersonate different roles. Probably the better thing  is to use an AuthorizationDomainService provided by the WCF RIA Services.

Once you add the RoleManager service to the App.xaml you can also specify a custom validator that will get the authorization requests and can apply every type of logic you need to perform the authorization. This class can be easily created by implementing the IRoleManagerValidator interface.

You can download the code of this article using the following link. I appreciate every suggestion to improve this extension.

Download: SLPG.MarkupExtensions.zip (30KB)

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Windows Phone 7 series continues...

2011-02-02T16:46:26+01:00 by Andrea Boschin

SilverlightShowAbout two weeks ago I started a series of articles about the Windows Phone 7 hosted by the well knows site SilverlightShow. In the very first rows of the opening article I wrote: "Starting with this article we will follow a path to discover one by one all the aspects of this device". The intent of the series is infact to give a walkthrough, starting from scratch, about the brand new device that is born in the previous months.

Now we are at the third number of the series and after having explained the most simple but not always obvious details of the UI, now it is time to go forward to explore the navigation paradigm that permeates you phone. This number will introduce to the problems of application lyfecycle and tombstoning that will be the argument of the fourth part I'm about to write.

If you have lost the previous number here is the links:

Windows Phone 7 Part #1: Getting Started

Windows Phone 7 Part #2: Your first app

As usual, if you have feedback or requests, you have only to write me or to Silverlightshow and we will fast answer to your needs.

Have a good reading

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Diet Assistant: track your diet with your Windows Phone

2011-01-24T22:56:00+01:00 by codeblock

Capture3Some days ago I released my second application for the Windows Phone. Probably it mean something I had a Windows Mobile device for the last four years and I never tried to write a single row of code and since last December, when I got my brand new HD7, I already wrote and published two applications.

The true story is that the hard part in realizing an application for Windows Phone 7 is to find a good idea. Discarded the possibility of making something unique the sole thing that you can do is try to find something you know well and write it as good as you can. 

So, given that I'm on diet from an unmemorable time it is probably the thing I better know, so I said to myself: why don't write and app to track my weight? I minute after I was head down to write it and I hope someone can find it useful almost the same as I enjoyed to write it.

The application is made of few pages and of a main dashboard that collect all the data you record to display a number of important parameters. I've tryed to imagine what I would like to know: the weight from which I started, the weight I've still to burn and an estimation of when I should reach my goal. You can see these and some other parameters in the figure on the left side.
 
There are two things I really enjoyed: first of all creating the gauge on top of this page gave me a deep respect to Blend that has been my best friend for this purpose. I think I will write a post about how to create a similar graphical element in the next days.

The second have been to create the transitions between pages when you navigate from a page to another. All the application became very dynamic thanks to these animations and for some days I have continuously tryed them on my phone only for the pleasure of seeing them playing.

The software uses Sterling to store the samples you record during the diet. Thanks to it is was very easy to create a log of all the data for the purpose of showing the history. You can also write a comment for each sample to remember something happen during the week.

The application require a regular sampling so the best is to put a recurring alert in the calendar to remember the date. It is a very bad thing being not able to do this from the application itself. I hope in the future this become possible.

Thanks of every comment.

New series of articles about WP7

2011-01-19T23:28:43+01:00 by Andrea Boschin

After a huge timeframe I return to my writing activity starting a series of articles about Windows Phone 7 for SilverlightShow website. During this time I've find the time to develop many samples for this device to prepare some speeches and I've created two applications for the marketplace.

The intent of the new series is to collect a number of articles, starting from scratch up to the very complicated subjects and I've started today with the very first and basic article about how to get started. In this article explain the architecture of the phone, and how to startup the development environment to be ready to write your own applications and deploy to the marketplace. Here is the planned table of contents of the series, but keep in mind that if you believe I miss something you can let me know and I manage to extend the series:

(19/1/2011)
 
Windows Phone 7 Part #2: Your first app
 
Windows Phone 7 Part #3: Understanding navigation
 
Windows Phone 7 Part #4: The application lifecycle
 
Windows Phone 7 Part #5: Panorama and Pivot controls
 
Windows Phone 7 Part #6: Advanced interaction
 
Windows Phone 7 Part #7: Understanding Push Notifications
 
Windows Phone 7 Part #8: Using Sensors

As you can see the road is long, since many arguments are covered by the series. I hope you will enjoy reading them but as I've already said if you think there is something to change contact me or the SilverlightShow website and we evaluate your proposals.

Few thoughts on PDC 2010 and the Silverlight destiny…

2010-10-29T22:45:18+01:00 by Andrea Boschin

There is not any doubt, the words I read today in this article and the complete lack of Silverlight during the PDC 2010 has been for me an hard blow. I put a great part of my work in this technology, I immediately recognized as my best friend for fast and reliable developing of applications. And I'm still convinced about this argument, also after the fashion of HTML5 has taken the scene few months ago and now that it has been promoted to a primary actor of the most important conference of Microsoft. This does not mean I really believe that Silverlight has been put in the trashcan and HTML5 has been suddenly put in its place. This will be a story about whom we will know in the next months and I'm confident that what appear to be real now will be demonstrated false soon.

I say these words not as a fanboy, but simply thinking at the reasons that moved me away from the HTML and Javascript world where I was really active. I remember the days when I spent my time trying to make HTML pages similar across four browser. I remember the days when I filled my code with message boxes just to try to understand why my javascript code did not work. I remember the frustrating hours I wasted to try to make good layouts with a technology that is not born to develop applications but only to display rich hypertexts. Yes, all we have to remember that HTML is not for applications. And it is not cross-platform. Developers makes it so. 

I started my story in Silverlight with the very first beta of the version 1.0 and I still have in my ears the voices of people saying: "puah... you have to develop with Javascript... you are crazy!". And they were right, Silverlight 1.0 was ugly because it did not resolved the main problem of the developers, the need of having reliable code that is something Javascript cannot give us. And even Javascript libraries like jQuery can't. I would like to know where are the people that write testable code, the ones that use dependency containers, design patterns, or simply the most effective coding tecniques that have its main reason in protecting the code from errors (expecially runtime errors) and give it maintainability and flexibility. While Silverlight enforces all these tecniques, Javascript doesn't. So the question I asked myself today was: is it what the people really wants?

And my answer is no. I'm confident people like to have effective applications that they can develop in less of half the time they have to use with other technologies. HTML5 will be for sure an interesting thing, but none has to confuse it with a development platform. HTML is the sole language that can be used for websites, where search engines make the difference, but when someone seriously wants to develop "applications", it is an insane choice. Now, and watching at the story behind HTML probably forever. I want to remembers, closing this post, that HTML5 now is far to be final. Just during the demo at the PDC they showed how differently it behave on different browsers and to me none can seriously believe that the actors in the scene will not try to catch HTML5 and make it a weapon to kill the other competitors. This is already happening.

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlightbox released on Codeplex

2010-10-18T00:03:08+01:00 by Andrea Boschin

Few hours ago I released a new project on Codeplex called Silverlightbox. The purpose of this project is to create a replacement for the javascript lightbox, used widely in many websites to display images and slideshows. The project works adding a silverlight overlay to the page that is showed when an hyperlink to an image is hit.

The Silverlightbox I released is compatible with the javascript lightbox. You can easily change the scripts of lightbox with my scripts and it works seamless without any change to the HTML already tagged for the lightbox. To have a look at how it appear try to click one of these images

Also if I'm a strong fan of Silverlight I provided the Silverlightbox with a minimal fallback javascript version that take place when the client does not have the plugin installed.

How to use Silverlightbox

To add the Silverlightbox to your website you have to link few script in the page. They are a cascading style sheet, the main silverlightbox.js script and the silverlight.js. You have also to link jQuery from the microsoft CDN. jQuery is used for the fallback javascript and for the part that query the page to find links to attach. Here is the code you have to add to the page <HEAD>

<link href="slb/sllightbox.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js"></script>
<script type="text/javascript" src="slb/silverlight.js"></script>
<script type="text/javascript" src="slb/silverlightbox.js"></script>


Once you have added the script to the page you can easily tag you hyperlink to show the silverlightbox. For this purpose you have to use the rel attribute and optionally specify a title attribute that is used to give a title to the displayed image. The code below show how to link an image to the Silverlightbox

<a href="http://blog.boschin.it/images/pics/DSC_6508.jpg" rel="lightbox" title="Dolphins 1">Show image</a>


Using a special syntax it is possible to create collection of images displayed ad slideshows. A slideshow have the navigation controls and let the user to move alogn the images without closinge the Silverlightbox. Here is how to create a slideshow

<a href="http://blog.boschin.it/images/pics/DSC_6511.jpg" rel="lightbox[dolphins]" title="Dolphins 2">Show image 1</a>
<a href="http://blog.boschin.it/images/pics/DSC_6516.jpg" rel="lightbox[dolphins]" title="Dolphins 3">Show image 2</a>
<a href="http://blog.boschin.it/images/pics/DSC_6519.jpg" rel="lightbox[dolphins]" title="Dolphins 4">Show image 3</a>
<a href="http://blog.boschin.it/images/pics/DSC_6522.jpg" rel="lightbox[dolphins]" title="Dolphins 5">Show image 4</a>

The code create a collection called "dolphins". You can have mltiple collections in a page using different names to group images each other.

Futures

I would want to continue the development of the Silverlightbox that now comes in the minimal release that cover the same features of the javascript counterpart. My intent is to add some interesting features:

1) autoplay of slideshows
2) support for video
3) customizable easing in and out
4) themes

Please let me know if there are other features you like and if you find any issue with the Silverlightbox. For this purpose please use the issue tracker on codeplex.

Link: http://silverlightbox.codeplex.com/

Tags:   , ,
Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Join Silverlight Firestarter!

2010-10-14T21:53:37+01:00 by Andrea Boschin

SLFirestarter_150X240

Silverlight Firestarter is a global event, stremed from Microsoft and presented by Scott Guthrie. During the event you can follw interesting sessions about Silverlight, k questions ad be in touch with your favorite technology.

It is an important event you cannot miss!

When: Thursday, December 2, 2010 8am to 5pm PT

Where: Microsoft corp, Redmond or Streamed Online

To register for the event follow this link and apply for in person or online registration form

http://www.silverlight.net/news/events/firestarter/

Capture

Tags:  
Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Chromeless Window for OOB applications in Silverlight 4.0 RC

2010-03-15T19:07:07+01:00 by Andrea Boschin

I think all of you are aware of the new useful features of Silverlight 4.0 beta released last November. I'm referringUntitled to a bunch of new improvements, affecting the out of browser applications, starting from the full-trust capabilities to the new Notification Window, and some little changes to the configuration of the window. The new release candidate of Silverlight 4.0 bring some news to the out of browser applications.

Until now we have a very little control over the window containing the application; we can configure the size and the positon on the screen and it is not possible to change them at runtime. With Silverlight 4.0 the Application class gain a new MainWindow proprty that expose a full set of tools to operate with the window. But this is not all the story. Using the project property we can also configure the window to be borderless and this let us draw our own chrome and manage window moving and resizing at runtime.

win The figure on the left show the configuration of the Window Style. It is available into the Out of browser settings window. Using NoBorder we can completely remove the default chrome of the window. Optionally we can also specify to have Round corners but there is not any configuration about the corner radius.

In the example attached to the end of this article I've created a simple control we can use to give a custom chrome to the window. The control has a template to customize the look and feel of the chromw and a buch of properties to define colors, and other aspects of the chrome. In the next paragraphs of this article I will show you how the control is built and how Silverlight let use easily customize the chrome in the release candidate bits.

The ApplicationWindow control

When we create a Silverlight application we usually define the MainPage.xaml as a UserControl, and this let us specify the markup of the page easily. Creating the ApplicationWindow control I decided to sobstitute it to the common UserControl so the control is defined as a ContentControl and we can change the markup like the code in this snippet:

   1: <controls:ApplicationWindow x:Class="SilverlightPlayground.GenericWindow.MainPage"
   2:                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:                             xmlns:controls="clr-namespace:SilverlightPlayground.Controls;assembly=SilverlightPlayground.Controls"
   7:                             Title="Tiny Browser"
   8:                             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
   9:     <Grid x:Name="LayoutRoot" Background="WhiteSmoke">
  10:  
  11:     </Grid>
  12: </controls:ApplicationWindow>

The control is a normal Templated Control and in the generic.xaml I've specified the default aspect of the window chrome. Some of the properties of the elements inside the template have been binded to the properties of the ApplicationWindow control so it is simple to change the Border color, the background, the font etc. Some elements has been defined as parts so I can attach some events and add the expected behavior to the window. When the user drag the chrome the window has to move on the screen and when the user drags the corner the window has to be resized.

The release candidate of Silverlight give us two methods doing the great part of the work. They ad DragResize and DragMove. In the control I attach the MouseLeftButtonDown event and in the handler I call one of these method to start the corresponding action. Here is the code:

   1: void Chrome_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   2: {
   3:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
   4:         Application.Current.MainWindow.DragMove();
   5: }
   6:  
   7: void ResizeHandle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   8: {
   9:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  10:         Application.Current.MainWindow.DragResize(WindowResizeEdge.BottomRight);
  11: }

The methods are so simple we really do not need to make any other action. After starting the action it detect the mouse and terminate the drag when the user release the button.

There is some other behaviors to implement. In the top right corner some buttons let the user close the window and operate like common windows minimizing and maximizing it. The MainWindow property has all the mehods and properties we need to make these buttons working. Here is some other code:

   1: void CloseButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions && !args.Cancel)
   4:         Application.Current.MainWindow.Close();
   5: }
   6:  
   7: void MaximizeButton_Click(object sender, RoutedEventArgs e)
   8: {
   9:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  10:     {
  11:         if (Application.Current.MainWindow.WindowState == WindowState.Normal)
  12:             Application.Current.MainWindow.WindowState = WindowState.Maximized;
  13:         else
  14:             Application.Current.MainWindow.WindowState = WindowState.Normal;
  15:     }
  16: }
  17:  
  18: void MinimizeButton_Click(object sender, RoutedEventArgs e)
  19: {
  20:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  21:         Application.Current.MainWindow.WindowState = WindowState.Minimized;
  22: }

The video at the end of the article show how the window appear. The control is almost complete to emulate the common windows but there is some other features we can use to manage the window:

Top, Left, Width & Height can be user programmatically to change the size of the window at runtime, Activate bring the window in front of the other window and finally the TopMost property can make it standing on top of other windows.

Source: SilverlightPlayground.GenericWindow.zip
Video: ChromelessWindow.wmv