Sunday, December 26, 2010

Microsoft Communities in Saudi Arabia 2009/2010 Story in Pictures

It' has been two years since I started working with the DevLifeStyle community in Saudi Arabia. The best thing about working the communities is that you get to meet with great people who share with you the same passion to technology. I’m really looking forward to continue our community efforts in the next year. In celebration of this occasion, I collected all the communities events pictures that I can get and put them inside the great Silverlight Pivot Collection Viewer.

Have a look  http://devlifestyle.net/CommunitiesPhotos/

Sunday, December 12, 2010

Join us at Riyadh Community Summit 23 December

Are you ready to attend our next community summit and have a chance to win XBOX or KINECT?

Detailed agenda can be found here

http://www.devlifestyle.net/RCS2

what do you think of this Silverlight invitation Smile

Friday, November 26, 2010

Silverlight 4.0 Tutorial (10 of N): Working with the PathListBox

You can find a list of the previous tutorial posts here

Continuing our RegistrationBooth Application, In this post we will make a change to the way we display the list of attendees. Currently we display them in a standard ListBox, we will replace this with a PathListBox, the PathListBox is a new customized control that comes with Blend SDK.

From its name this control is a list box however its elements are placed on whatever path you draw so instead of having our attendees placed vertically in the ListBox we will have our attendees placed along the path we will draw, let’s start by deleting the existing ListBox.

First thing is to draw the path on which we will display the attendees, we will draw a big arc and place it in the left corner, drag an arc shape from the assets window

Drawing an arc

Drop it on the left column and set the StartAngle to 0 and the EndAngle to 180 to make the arc like a half ellipse

2

To convert this into a PathListBox, right click on the arc and select Path->Make Layout Path

Make Layout Path

A PathListBox will be added to the page, rename it to lstAttendees

the attendees PathListBox

We will bind the ItemsSource property of the PathListBox to our attendees DomainDataSource control

Binding the ItemsSource property

Next we will change the ItemTemplate property, we already have a DataTemplate defined for the attendees in the local resources, so we will bind to this template

Bindin the ItemTemplate

We will also set the Capacity property to 4, this property determines the number of items shown on the Path.

Set the Start property to 20%, this property determines the distance from the start of the Layout Path to place the first item.

Set the Span property to 80%, this property determines the percentage of the Layout Path that participates in layout.

 LayoutPath Properties

Let’s run the application and see what we have till now, you will see 4 attendees placed over the layout path we created.

The list of attendees placed over the arc

To see the rest of the attendees we need to add scrolling to the PathListBox, this will require some coding but Luckily for us the Expression Blend team has already done this in the PathListBoxUtils library which is a collection of behaviors, controls and extensions for the PathListBox, you can download it from the Expression Blend Codeplex site

First we will add two buttons one above the PathListBox we will name it BackButton and one below the PathListBox we will name it ForwardButton. we need to wire these two buttons to move backward/forward through the PathListBox items. to do this we will use a behavior that comes with the PathListBoxUtils library.

Drag the PathListBoxScrollBehavior and drop it over our PathListBox

PathListBoxScrollBehavior

From the properties of the PathListBoxScrollBehavior add an EventTrigger for the DecrementCommand, set the SourceObject to the BackButton and set the EventName to Click.

PathListBoxScrollBehavior DecrementCommand

Add an EventTrigger for the IncrementCommand, set the SourceObject to the ForwardButton and set the EventName to Click.

PathListBoxScrollBehavior IncrementCommand

Add an EventTrigger for the ScrollSelectedCommand, set the EventName to SelectionChanged.

PathListBoxScrollBehavior ScrollSelectedCommand

We will associate an easing function with this behavior so that the scrolling looks more fancy.

Easing function

Run the application and click the forward button to see the scrolling in action

PathListBox scrolling

You can download the source code from here.

See you in the next post.

Tuesday, November 09, 2010

Silverlight 4.0 with SharePoint 2010 (2 of 2)

In the previous post we set the stage for how can we start building Silverlight applications for SharePoint 2010

You have three options to actually program against the SharePoint from Silverlight: First there’s the SharePoint web services that have been there for a long time, Second there’s the new REST APIs that is suitable for working with strongly typed lists and the final option is the Client Object Model.

The Client Object Model is a simple to use API that can be called from .NET CLR, JavaScript or Silverlight, we will stick with the Client Object Model cause this is the most suitable one to use from Silverlight, If you are familiar with developing for SharePoint on the Server Side (using SPWeb, SPList, etc.) then you will find that the COM (Client Object Model) mirrors a subset of the objects that are on the server.

For Silverlight applications you need to reference the COM APIs there are two DLLs that you need to reference in your Silverlight project Microsoft.SharePoint.Client.Silverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll, you can find these DLLs in the following path

“C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin”

So let’s start creating the Silverlight application, we will create two projects a SharePoint project and a Silverlight project and configure the SharePoint project to to deploy the Silverlight xap file (refer to the first post for more details).

in the Silverlight project, add reference to the two COM assemblies

Adding reference to the Silverlight COM assemblies

we will build a simple Guest Book Silverlight Application, it will display a list of guests and allow the user to add new guests, here’s how the application looks like

a Simple Silverlight GuestBook Application

The code is very straightforward, we have a view model that represents the Guests, the view model contains a collection of Guests that is bound to a ListBox in the xaml file, the add button is bound to a Command on the view model that adds a new Guest with the information entered by the user, the view model class is shown below

  1. public class GuestsViewModel : INotifyPropertyChanged
  2.     {
  3.         public GuestsViewModel(){}
  4.         GuestsStore _guestStore = new GuestsStore();
  5.         public ObservableCollection<Guest> Guests
  6.         {
  7.             get
  8.             {
  9.                 var res = new ObservableCollection<Guest>();
  10.                 var lst = _guestStore.RetrieveGuests();
  11.                 foreach (var gst in lst)
  12.                 {
  13.                     res.Add(gst);
  14.                 }
  15.                 return res;
  16.             }
  17.         }
  18.  
  19.         Guest _newGuest = new Guest();
  20.         public Guest NewGuest
  21.         {
  22.             get { return _newGuest; }
  23.         }
  24.  
  25.         public event PropertyChangedEventHandler PropertyChanged;
  26.         protected void NotifyPropertyChanged(string propertyName)
  27.         {
  28.             if (PropertyChanged != null)
  29.             {
  30.                 PropertyChanged(this,
  31.                 new PropertyChangedEventArgs(propertyName));
  32.             }
  33.         }
  34.         bool AddNewGuest()
  35.         {
  36.             _guestStore.AddGuest(_newGuest);
  37.             _newGuest = new Guest();
  38.             NotifyPropertyChanged("Guests");
  39.             NotifyPropertyChanged("NewGuest");
  40.             return true;
  41.         }
  42.  
  43.         private AddGuestCommand _addGuestCommand = null;
  44.         public AddGuestCommand AddGuestCommand
  45.         {
  46.             get
  47.             {
  48.                 if (_addGuestCommand == null)
  49.                 {
  50.                     _addGuestCommand = new AddGuestCommand
  51.                     (
  52.                     p => AddNewGuest(),
  53.                     p => true
  54.                     );
  55.                 }
  56.                 return _addGuestCommand;
  57.             }
  58.         }
  59.     }
  60.     public class AddGuestCommand : ICommand
  61.     {
  62.         public AddGuestCommand(Action<object> executeAction,
  63.                         Predicate<object> canExecute)
  64.         {
  65.             if (executeAction == null)
  66.                 throw new ArgumentNullException("executeAction");
  67.             _executeAction = executeAction;
  68.             _canExecute = canExecute;
  69.  
  70.         }
  71.  
  72.         private readonly Predicate<object> _canExecute;
  73.         public bool CanExecute(object parameter)
  74.         {
  75.             if (_canExecute == null) return true;
  76.             return _canExecute(parameter);
  77.         }
  78.  
  79.         public event EventHandler CanExecuteChanged;
  80.         public void OnCanExecuteChanged()
  81.         {
  82.             if (CanExecuteChanged != null)
  83.                 CanExecuteChanged(this, EventArgs.Empty);
  84.         }
  85.  
  86.         private readonly Action<object> _executeAction;
  87.         public void Execute(object parameter)
  88.         {
  89.             _executeAction(parameter);
  90.         }
  91.  
  92.     }

In the code behind file MainPage.xaml.cs of the main page, the view model is set as the DataContext of the entire page

  1. public partial class MainPage : UserControl
  2.     {
  3.         public MainPage()
  4.         {
  5.             InitializeComponent();
  6.             this.DataContext = new GuestsViewModel();
  7.         }
  8.     }

The xaml is shown below

  1. <UserControl x:Class="SilverlightSP.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.     mc:Ignorable="d"
  7.     d:DesignHeight="300" d:DesignWidth="400">
  8.     <UserControl.Resources>
  9.         <Style TargetType="TextBlock">
  10.             <Setter Property="Foreground" Value="White" />
  11.         </Style>
  12.         
  13.         <DataTemplate x:Key="personDataTemplate">
  14.             <Grid Margin="10">
  15.                 <Border Width="300" Padding="20" Grid.Row="0" Grid.ColumnSpan="2" Height="100"
  16.             Background="#FFED2D59" CornerRadius="20" >
  17.                     <Grid Margin="10">
  18.                         <Grid.RowDefinitions>
  19.                             <RowDefinition/>
  20.                             <RowDefinition/>
  21.                             <RowDefinition/>
  22.                         </Grid.RowDefinitions>
  23.                         <Grid.ColumnDefinitions>
  24.                             <ColumnDefinition Width="0.3*" />
  25.                             <ColumnDefinition Width="0.7*"/>
  26.                         </Grid.ColumnDefinitions>
  27.                         <TextBlock Grid.Row="0" Grid.Column="0">First Name:</TextBlock>
  28.                         <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding FirstName}" />
  29.                         <TextBlock Grid.Row="1" Grid.Column="0">Last Name:</TextBlock>
  30.                         <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LastName}" />
  31.                         <TextBlock Grid.Row="2" Grid.Column="0">Email:</TextBlock>
  32.                         <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Email}" />
  33.                     </Grid>
  34.                 </Border>
  35.             </Grid>
  36.         </DataTemplate>
  37.     </UserControl.Resources>
  38.     <Grid x:Name="LayoutRoot">
  39.         <Grid.RowDefinitions>
  40.             <RowDefinition Height="0.677*"/>
  41.             <RowDefinition Height="0.323*"/>
  42.         </Grid.RowDefinitions>
  43.         <Grid.Background>
  44.             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  45.                 <GradientStop Color="#FF5E48CC" Offset="0"/>
  46.                 <GradientStop Color="#FF281297" Offset="1"/>
  47.                 <GradientStop Color="#FF644FCE" Offset="0.493"/>
  48.             </LinearGradientBrush>
  49.         </Grid.Background>
  50.         <ListBox Width="400" ItemsSource="{Binding Guests}" Margin="10"
  51.                           ItemTemplate="{StaticResource personDataTemplate}" Background="{x:Null}" BorderBrush="{x:Null}"
  52.                           />
  53.         <Grid Grid.Row="1" Width="400" Height="100" >
  54.             <Grid.ColumnDefinitions>
  55.                 <ColumnDefinition Width="0.2*"/>
  56.                 <ColumnDefinition Width="0.3*"/>
  57.                 <ColumnDefinition Width="0.2*"/>
  58.                 <ColumnDefinition Width="0.3*"/>
  59.             </Grid.ColumnDefinitions>
  60.             <Grid.RowDefinitions>
  61.                 <RowDefinition Height="0.5*"/>
  62.                 <RowDefinition Height="0.5*"/>
  63.             </Grid.RowDefinitions>
  64.             <TextBlock Grid.Row="0" Grid.Column="0" Margin="10,0,0,0">First Name:</TextBlock>
  65.             <TextBox Grid.Row="0" Text="{Binding NewGuest.FirstName,Mode=TwoWay}" Grid.Column="1" x:Name="txtFirstName" Height="25" VerticalAlignment="Top" />
  66.             <TextBlock Grid.Row="0" Grid.Column="2" Margin="10,0,0,0">Last Name:</TextBlock>
  67.             <TextBox Grid.Row="0" Text="{Binding NewGuest.LastName,Mode=TwoWay}" Grid.Column="3" x:Name="txtLastName" Height="25" VerticalAlignment="Top" />
  68.             <TextBlock Grid.Row="1" Grid.Column="0" Margin="10,0,0,0">Email:</TextBlock>
  69.             <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding NewGuest.Email,Mode=TwoWay}" x:Name="txtEmail" Height="25" VerticalAlignment="Top" />
  70.             <Button Grid.Row="1" Grid.Column="2" x:Name="btnAdd"
  71.                     Content="Add" VerticalAlignment="Top" Margin="10,0,0,0"
  72.                     Command="{Binding AddGuestCommand}"/>
  73.         </Grid>
  74.     </Grid>
  75. </UserControl>

In the view model you can see that we are using a repository for the Guests implemented using the GuestStore class, this class simply stores the guests in an internal list

  1. public class Guest
  2.     {
  3.         public string FirstName { get; set; }
  4.         public string LastName { get; set; }
  5.         public string Email { get; set; }
  6.     }
  7.     public class GuestsStore
  8.     {
  9.         private List<Guest> _guests = new List<Guest>();
  10.  
  11.         public GuestsStore()
  12.         {
  13.             _guests= new List<Guest>() {
  14.             new Guest(){ FirstName="Mohamed", LastName="Mosallem",Email="mmosalem@devlifestyle.net"},
  15.             new Guest(){ FirstName="Ahmed", LastName="Ismail",Email="aismail@yahoo.com"},
  16.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  17.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  18.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  19.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  20.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  21.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  22.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"},
  23.             new Guest(){ FirstName="Ibrahim", LastName="Mahmoud",Email="imahmoud@hotmail.com"}
  24.             };
  25.         }
  26.  
  27.         public List<Guest> RetrieveGuests()
  28.         {
  29.             return _guests;
  30.         }
  31.         public bool AddGuest(Guest g)
  32.         {
  33.             _guests.Add(g);
  34.             return true;
  35.         }
  36.     }

Till now this is a normal Silverlight application no SharePoint yet, what we will do is that, we will create a custom SharePoint list to store the Guests in it, and we will use our Silverlight application to populate this list, so let’s create the custom list in SharePoint.

From the Site Actions menu choose Create, in the Create Dialog select Custom List, name it GuestBook

Create Custom List

On the ribbon go to the List menu, click the Create Column button Create Column

Fill the necessary information and repeat this step for the three columns “First Name” , “Last Name” and “Email”

Create Column Dialog

The next step is to change our Silverlight application to read/write to the GuestBook list. Most of the changes will be in the GuestsStore class, we will remove the internal list we used before.

The central object to start with while programming against the SharePoint COM is the ClientContext which represents the SharePoint Context in which the client (in our case the Silverlight application) is running, one important concept in SharePoint COM is that before you access a property or object you have to ask for it, let’s walkthrough the RetrieveGuests method

  1. public void RetrieveGuests()
  2.       {
  3.          var clientContext = ClientContext.Current;
  4.          var guestBookList = clientContext.Web.Lists.GetByTitle("GuestBook");

First we grab a reference to the current ClientContext, then we define an object that will reference our list (you can see that the object model is very similar to the SharePoint server API).

after that we ask the client context to load the list items

  1. clientContext.Load(_guestsListItems,
  2.                        items => items.Include(
  3.                                item => item[FirstNameColumn],
  4.                                item => item[LastNameColumn],
  5.                                item => item[EmailColumn]
  6.                             )
  7.                            );

As you can see we explicitly asked the clientContext to Include the columns we are interested in.

The clientContext.Load doesn’t actually call to the server and retrieve the list item instead it just builds up the request that will be sent to the server, so basically we can batch multiple operations together to be executed as batch on the server, to actually send the request to the server we call the clientContext.ExecuteQuery method

  1. clientContext.ExecuteQueryAsync(
  2.                 new ClientRequestSucceededEventHandler(GuestsRetrievedSucceeded),
  3.                 null);

We used the async version of the method, this method accepts a callback function to be called when ExceuteQuery succeeds

  1. void GuestsRetrievedSucceeded(object sender, ClientRequestSucceededEventArgs args)
  2.         {
  3.             if (GuestsRetrieved != null)
  4.             {
  5.                 List<Guest> res = new List<Guest>();
  6.                 foreach (var item in _guestsListItems)
  7.                 {
  8.                     res.Add(new Guest()
  9.                     {
  10.                         FirstName = item[FirstNameColumn].ToString(),
  11.                         LastName = item[LastNameColumn].ToString(),
  12.                         Email = item[EmailColumn].ToString()
  13.                     });
  14.                 }
  15.                 GuestsRetrieved(res);
  16.             }
  17.         }

In this event handler we populate a list of Guests from the SharePoint list items and then fire a custom event GuestRetrieved, the view model subscribes to this event.

The AddGuest method is very simple, we define a new list item and set its field values, then submit this to the server, and fire an event if this succeeds

  1. public void AddGuest(Guest g)
  2.         {
  3.             var clientContext = ClientContext.Current;
  4.             _newGuest = g;
  5.             var guestBookList = clientContext.Web.Lists.GetByTitle("GuestBook");
  6.          
  7.             ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
  8.             ListItem newGuestListItem = guestBookList.AddItem(itemCreateInfo);
  9.             newGuestListItem[FirstNameColumn] = g.FirstName;
  10.             newGuestListItem[LastNameColumn] = g.LastName;
  11.             newGuestListItem[EmailColumn] = g.Email;
  12.             newGuestListItem["Title"] = g.FirstName + " " + g.LastName;
  13.             newGuestListItem.Update();
  14.  
  15.             clientContext.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(GuestAddedSucceeded), null);
  16.         }
  17.         
  18.         void GuestAddedSucceeded(object sender, ClientRequestSucceededEventArgs args)
  19.         {
  20.             if (GuestAdded != null)
  21.             {
  22.                 GuestAdded(_newGuest);
  23.             }
  24.         }

Here’s the application running inside SharePoint

The Silverlight application running inside SharePoint

This is just a simple basic Silverlight application, let’s add a simple enhancement that can make our Silverlight application shine within SharePoint, to do this we will use Expression Blend, right click on the MainPage.xaml file and select Open in Expression Blend

Open in Expression Blend

Right click on the ListBox and select Edit Additional Templates-> Edit Generated Item Container-> Edit a Copy

Edit Generated Item Container

Click Ok in the Create Style Dialog

On the states tab set the transition duration for the LayoutStates group to 1 second

Set the transition duration

While the BeforeLoaded state is selected, select the grid element from the Objects and Timeline tool window, go to the properties window and change the Opacity property to 0% and change the Translate transform Y property to 100

 Changing the Opacity and translating the ListBox

The last thing is to click on the small icon to Turn on FluidLayout

Turn on FluidLayout

Now build and run the application, you notice a very nice effect when adding elements to the list.

That’s the end of this post, hope this was useful.

You can download the source code from here

P.S: you will notice that the column names in the code don’t match the names we specified in SharePoint, please refer to this blog post for more details

Monday, November 01, 2010

HTML5 and Silverlight: The hype is over. Thanks Bob!

After a long week full of confusion, controversy and anger, Bob Muglia provide more clarification.

Kill Silverlight?! what did you think guys?! For GOD’s sake Silverlight is not the Ugly Kin to simply terminate like this.

By the way, too many “Is Silverlight Dead?” screams out there but no “Is Flash Dead?” ! does this tell anything?!

Saturday, October 30, 2010

Silverlight 4.0 with SharePoint 2010 (1 of 2)

It’s been a while since I used SharePoint as I was focusing lately on Silverlight, In this post I will start exploring how to use Silverlight 4.0 with SharePoint 2010, I must mention that I’m not a SharePoint expert so please feel free to update me if there’s something mentioned that is not correct.

What I like about SharePoint 2010 is that Silverlight comes right out of the box. The first thing you will note when you access SharePoint2010 sites (assuming that you have Silverlight installed) is that SP2010 makes use of Silverlight in many places, for example the Create Dialog is a just a Silverlight application

The Silverlight Create Dialog in SharePoint2010

Also the videos you upload to SP2010 assets libraries are played using a Silverlight media player

Silverlight Media Player

the entry point for you Silverlight application into SharePoint is the Silverlight Web Part which is built into SP2010, you can insert this web part into any web page

Insert a Silverlight Web Part

Let’s try to use this web part, first we will create a Silverlight application, Start Visual Studio –> Create a new Silverlight Application, no need to create a web application to host the Silverlight application as we will be hosting it inside SharePoint.

The Silverlight application is very simple, we have a TextBlock and a Button

  1. <Grid x:Name="LayoutRoot" Background="White">
  2.     <StackPanel VerticalAlignment="Center">
  3.         <TextBlock Width="200" x:Name="lbl"></TextBlock>
  4.         <Button Content="Click Me" Width="200" Click="Button_Click"></Button>
  5.     </StackPanel>
  6. </Grid>

When we click the button we set the text of the TextBlock

  1. private void Button_Click(object sender, RoutedEventArgs e)
  2.         {
  3.             lbl.Text = "Hello SharePoint2010";
  4.         }

After we build the application we will have the xap file, upload this file to a document library on the SharePoint site

Uploading the xap file to SharePoint

Once the xap file is uploaded we need to copy its URL, right click the xap file in the documents list and select copy shortcut

5

Now we will add a Silverlight Web Part to host our application, So edit the current page in SharePoint and go to the Insert tab and Click on the Web Part button

6

Select the Silverlight Web Part (inside the Media and Content category) and click Add

7

A dialog box will ask you to specify the URL of the xap file, paste the URL of the xap file that you uploaded to the document library

8

Save the page to exit the edit mode, now try to click the button to see the text in the label

9

You can edit the web part to see its properties, you will find the default properties (Width, height, etc.), you can also change the xap file or you can pass custom initialization parameters to Silverlight

10

So now we saw how we can run a Silverlight application inside SharePoint, for smooth development it’s not convenient to go and upload the xap file to SharePoint manually, we can solve this by using VS2010 support for SharePoint, let’s start by adding a new empty SharePoint project to the Solution we had earlier. specify the site that you will use for debugging and choose the trust level to be sandboxed solution, the solution should look like the following

 11

To deploy files to SharePoint you must add a Module to the SharePoint project let’s call it SilverlightApp

12

Visual Studio will add a sample.txt file, we need to replace this by the xap file, to do this first delete the sample.txt file then click on the SilverlightApp module in the Solution Explorer and go to the Properties window click the ellipse beside the property Project Output References 

13

The Project Output References dialog box will appear, click the Add button, Set the Project Name property to the Silverlight project and set the Deployment Type property to ElementFile

Adding The Silverlight project output to the SharePoint Module

Open the Elements.xml file, you can see our xap file specified inside the Module, change the Url attribute to point to a location inside the Master Pages document library, the Elements.xml file should look like the following

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  3.   <Module Name="SilverlightApp">
  4.     <File Path="SilverlightApp\SilverlightSP.xap"
  5.           Url="_catalogs/masterpage/SilverlightApp/SilverlightSP.xap" />
  6.   </Module>
  7. </Elements>

Now we are set to go, Set the SharePoint project as a startup project then Press F5 to deploy the solution to SharePoint. to verify that the solution was installed successfully go to Site Actions-> Site Settings–> Galleries–> Solutions, you should see our SharePointSL solution there

SharePoint Site Solution Gallery

Now we will add a Silverlight Web Part and set the Url of the xap file to the path we specified in the Module file (/_catalogs/masterpage/SilverlightApp/SilverlightSP.xap)

And you should be able to see the SL application running.

Another thing you will definitely need when you start developing Silverlight applications for SharePoint is debugging, you can easily enable this by going to the SharePoint project properties, on the SharePoint tab check the “Enable Silverlight debugging” check box.

Enabling Silverlight Debugging from a SharePoint project

To test this let’s add a breakpoint in our Silverlight application, we will add the breakpoint inside the Button click event handlers, Press F5 to start debugging, go to the Silverlight web part, click the button and you should be switched back to VS

Debugging Silverlight From SharePoint

That is pretty much it for this post, we saw how we can start integrating Silverlight into SharePoint 2010, in the next post we will see how we can program against SharePoint from within Silverlight.

Friday, October 08, 2010

Join us @ ROCS

The first Riyadh Online Community Summit (ROCS) will be held on 21-22 October. this is the first online event in Riyadh organized by Riyadh Communities (RSUG, DevLifeStyle, WindowsPhoneME), we are having speakers from the local communities as well as MVPs from all over the world.

the detailed agenda can be found here

http://rocs1.eventbrite.com/

Registration link

https://www2.gotomeeting.com/register/208245435

Thursday, October 07, 2010

Silverlight 4.0 Tutorial (9 of N): Using the WebCam as a Barcode Scanner

You can find a list of the previous tutorial posts here

Continuing our RegistrationBooth Application, we want to allow registered users to evaluate sessions, we don’t have a credentials store in our application so to identify the registered attendees we will use a simpler approach, in part2 we allowed printing a name tag for registered attendees, this name tag contains a barcode of the attendee id, in this post we will see how can we use the new Silverlight 4.0 WebCam functionality to be able to scan/read barcodes and extract the attendee id to identify the corresponding attendee.

During PDC09 Keynote, Scott Guthrie demonstrated a Silverlight Application that scans a book ISBN barcode and passes this ISBN to Amazon web service to retrieve the book information, we will reuse the code from this sample which can be downloaded from here.

This sample actually uses a code from a CodeProject Article (by Berend Engelbrecht) that detects barcodes inside an image. the code is located in the file BarcodeImaging.cs, so we will copy this file to our project.

The sample also has another class BarcodeCapture that derives from VideoSink, according to MSDN “To obtain video information from a video input device in Silverlight, you derive a custom video sink from VideoSink” , the important method to override in this class is OnSample which is called when the video device captures a complete video sample. the code in this method calls the BarcodeImaging method that scans the current sample bitmap for a barcode, if a barcode is found the BarcodeCapture class fires a custom event BarcodeDetected that propagates the detected barcode. so we will need to copy the BarcodeCapture.cs file to our project.

On the UI we will have two components, the first one is a rectangle that we will display the webcam stream inside it.

<Border x:Name="nameTagScannerArea" Padding="10" Grid.Column="1" Height="400" Grid.RowSpan="2" Background="{StaticResource greenBrush}" CornerRadius="30" d:IsHidden="True" >
        <StackPanel>
            <TextBlock TextAlignment="Center" FontSize="14.667" FontWeight="Bold" Foreground="White" >Place your name tag infront of the camera</TextBlock>
            <Rectangle x:Name="barcodeScanner" Fill="White" Width="400" Height="300"          />                  
     </StackPanel>
    </Border>

The second UI component is another rectangle that will be shown when a barcode is detected, the rectangle will display a simple welcome message to the user, we will add more functionality later.

<Border x:Name="welcomeArea" Padding="10" Grid.Column="1" Height="150" Grid.RowSpan="2" Background="{StaticResource orangeBrush}" CornerRadius="30" >
         <StackPanel Orientation="Horizontal">
         <TextBlock TextAlignment="Center" FontSize="14.667" VerticalAlignment="Center" FontWeight="Bold" Foreground="White" >Welcome </TextBlock>          
         <TextBlock x:Name="userName" TextAlignment="Center" FontSize="14.667" VerticalAlignment="Center" FontWeight="Bold" Foreground="White" ></TextBlock>          
         </StackPanel>
    </Border>

We will add two new visual states, the first one is “ScanningNameTag” in this state we display the barcode scanning area and the attendee list, here’s how the UI looks like in this state

ScanningNameTag State

The button “Back” moves the UI back to the Default state by using a MoveToStateAction behavior

 MoveToStateAction behavior to go to the Default State

The second state is “WelcomeAttendee”, in this state we show the welcome area and the attendee list, here’s how the UI looks like in this state

WelcomeAttendee State

As you can see we added a Good Bye Button (btnLogout), we will add a MoveToStateAction behavior to this button so that when we click it we move to the Default state

The logout button takes us back to the default state

when we click the  “Login” button, we will start the cam and move to the “ScanningNameTag” state

private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            if (ActivateCamera())
            {
                if (m_Capture == null)
                {
                    m_Capture = new BarcodeCapture();
                    m_Capture.BarcodeDetected += new EventHandler<BarcodeEventArgs>(OnBarcodeDetected);
                    m_Capture.CaptureSource = m_CaptureSource;
                }
                VisualStateManager.GoToState(this, "ScanningNameTag", true);
            }
        }

The code first activates the camera to start capturing by calling the ActivateCamera function shown below

bool ActivateCamera()
        {
            if (m_CaptureSource == null)
            {
                m_CaptureSource = new CaptureSource();
                m_CaptureSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                VideoBrush previewBrush = new VideoBrush();
                previewBrush.Stretch = Stretch.Uniform;
                previewBrush.SetSource(m_CaptureSource);
                barcodeScanner.Fill = previewBrush;

                Size diff = new Size(double.MaxValue, double.MaxValue);
                Size wantedSize = new Size(640, 480);
                VideoFormat bestFormat = null;
                foreach (VideoFormat format in m_CaptureSource.VideoCaptureDevice.SupportedFormats)
                {
                    double x = Math.Abs(format.PixelWidth - wantedSize.Width);
                    double y = Math.Abs(format.PixelHeight - wantedSize.Height);

                    if (x < diff.Width && y < diff.Height)
                    {
                        bestFormat = format;
                        diff.Width = x;
                        diff.Height = y;
                    }
                }
                if (bestFormat != null)
                {
                    m_CaptureSource.VideoCaptureDevice.DesiredFormat = bestFormat;
                }
                if (CaptureDeviceConfiguration.RequestDeviceAccess() || CaptureDeviceConfiguration.AllowedDeviceAccess)
                {
                    m_CaptureSource.Start();
                    return true;
                }
                else
                    return false;
            }
            else
                return true;
        }

after starting the camera we create an instance of our VideoSink (BarcodeCapture) and link the capture source with our video sink, we must also register to the event BarcodeDetected to be notified when the BarcodeCapture video sink detects a barcode in the image.

Here is the event handler for the BarcodeDetected event

void OnBarcodeDetected(object sender, BarcodeEventArgs e)
        {
            if (e.Barcode.Length < 8)//barcode formate is ATTXXXXX
                return;

            int attendeeID=0;
            if (!Int32.TryParse(e.Barcode.Substring(3, 5), out attendeeID))
                return;

            Dispatcher.BeginInvoke(delegate()
            {
                RegistrationDomainContext context = this.Resources["registrationDomainContext"] as RegistrationDomainContext;
                context.Load(context.GetAttendeeQuery(attendeeID),
                        delegate(LoadOperation<Attendee> loadOperation)
                        {
                            m_CaptureSource.Stop();
                            m_Capture.Clear();
                            foreach (var attendee in loadOperation.Entities)
                            {
                                lblUserName.Text = string.Format(" {0} {1}", attendee.FirstName ,attendee.LastName);
                                break;
                            }
                            VisualStateManager.GoToState(this, "WelcomeAttendee", true);
                        },
                        null);
            });
        }

First We validate the barcode format, then we call a new domain service method that retrieves the attendee based on the id, note that we are using Dispatcher.BeginInvoke method so that our code runs on the main UI thread.

Let’s run the application, click on the Login button, the webcam will start, hold the name tag in front of the webcam, you may need to move the name tag closer/way from the webcam till it picks the barcode

Barcode scanning through the web cam

Once the barcode is detected, the application will move to the WelcomeAttendee state

5

Note: i used the Silverlight Barcode Library to generate the barcode, cause the previous method we used (the font 3 of 9) was not recognized by Berend library

You can download the source code from here.

See you in the next post.