DCSIMG
Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 1 - Johnny's RIA Corner

Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 1

So, my first REAL post of 2011... Let's make it count!

A few days ago i started looking into the possibility of integrating Silverlight into the SharePoint 2010 Ribbon control. Naturally i checked my favorite blogs to see if someone has experimented with this already but i couldn't find a single mention of Silverlight and the ribbon working together, so i decided to create a small, fun (and to be honest quite useless) POC of using Silverlight as a control inside the SharePoint 2010 ribbon. The POC is a small Silverlight galley control, which shows the thumbnails of a random image folder on our site, and will be shown on a special tab on our ribbon once we browse the content of a document folder. 

Start by downloading the starter project and open it with Visual Studio 2010.

The solution is divided into two projects:

  • A SharePoint project with a module (to upload our Silverlight .xap file) and an empty element (which we will use to define our custom ribbon control).
  • A Silverlight project that for our thumbnail gallery.

We will start with getting the Silverlight part to work and then move on to define our new custom ribbon control.

1) Open MainPage.xaml and inspect the code. You'll see that the xaml is basically just a grid containing two images for arrows (thanks openclipart.org!) and a listbox that has a style which hide the horizontal and vertical scroll bars. We need these bars hidden since we want to use the arrow images to control the listbox view.

2) Since we are going to use SharePoint's Client Object Model, we need to add it's dlls to our project. Right click on "References", then "Add Reference", "Browse", navigate to "C:\Program Files\Common Files\Microsoft Shared\Web Server Extension\14\TEMPLATE\LAYOUTS\ClientBin" and select the two dll files. Finally click OK.

3) Open MainPage.xaml.cs and add the following using statement:

using Microsoft.SharePoint.Client;

4) We need 4 private variables to hold information trough out the code: the client object model's client context (_context), the lists collection of our web (_lists), a variable to hold the actual items (_imagesCollection) from the random gallery and a counter we will use to flip through the images once they are binded to the listbox. Add the following variables right after the class declaration: 

private ClientContext _context;
private ListItemCollection _imagesCollection;
private
ListCollection _lists;
private
int _imageCounter; 

5) Add an event listener for the loaded event in your MainPage constructor, so that your constructor looks like that:


public MainPage()
{
    InitializeComponent();
   
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

6) Now it’s time to initialize the client context object and get the collection of lists from our site. Copy the following code so your MainPage_Loaded method looks like this:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    _context =
new ClientContext(ApplicationContext.Current.Url);
    _lists = _context.Web.Lists;
    _context.Load(_lists,i=>i.Include(j=>j.ContentTypes,j=>j.Title));
    _context.ExecuteQueryAsync(OnGetListsSucceeded, OnRequestFailed);
}
  • On the first line we initialize our context to the current site we are working on using the ApplicationContext object.
  • On the second line we ask to get all the lists of the current site.
  • On the third line we tell the client context to load the lists collection but only include the content types collection (so we can later filter it by the Picture content type) and the title (so we can later load only that list by its title).
  • On the final line is where the magic happens and our request is sent back to the server to get the information we need.

OnGetListsSucceeded will be called if our request has gone through successfully while OnRequestFailed will get called if our request failed.

7) Add the OnGetListSucceeded and OnRequestFailed methods to our MainPage.cs:

private void OnGetListsSucceeded(object sender, ClientRequestSucceededEventArgs e)
{
   
this.Dispatcher.BeginInvoke(ChooseGalleryAndGetItems);
}


private
void OnRequestFailed(object sender, ClientRequestFailedEventArgs e)
{
   
this.Dispatcher.BeginInvoke(() => PrintErrorInformation(e));
}

If you are new to SharePoint's client object model you may be wondering why we are using Dispatcher.BeginInvoke on these methods.
The answer is quite simple: The client object model runs on a different thread then our UI thread so if we want to invoke something that is on another thread (in our case the UI thread) we use Dispatcher.BeginInvoke() and pass it the method we wish to call.
You may also notice that OnRequestFailed is calling a method named "PrintErrorInformation" and passing it the ClientRequestFailedEventArgs variable. This method is a generic method that will always print the cause for error for the specific call by using the information passed to it by the eventargs object.

8) Add the PrintErrorInformation method to your code:

private void PrintErrorInformation(ClientRequestFailedEventArgs e)
{
   
MessageBox.Show("Request failed:" + e.Message + "\nStack Trace:" + e.StackTrace + "\nDetails:" + e.ErrorDetails + "\nValue:" + e.ErrorValue);
}

9) Add the ChooseGalleryAndGetItems method (the method that gets called when the request succeessful) to your code:

private void ChooseGalleryAndGetItems()
{
   
ObservableCollection<List> galleries = new ObservableCollection<List>();
   
foreach (List list in _lists)
    {
       
if (list.ContentTypes[0].Name == "Picture")
        galleries.Add(list);
    }
   
   
List selectedGallery =_context.Web.Lists.GetByTitle(galleries[new Random().Next(0, galleries.Count - 1)].Title);
    _context.Load(selectedGallery);
    _imagesCollection = selectedGallery.GetItems(
new CamlQuery() { ViewXml = "<View/>" });
    _context.Load(_imagesCollection,image=>image.Include(i=>i[
"LinkFilename"],i=>i["EncodedAbsUrl"]));
    _context.ExecuteQueryAsync(OnGetItemsSucceeded, OnRequestFailed);
}

The methods build an ObservableCollection of lists which have the content type of Picture, then select one randomly using Random object and finally loads all the items to the _imagesCollection object we created earlier. As before nothing get sent back to the server before the ExecuteQueryAsync fires up.

10) Add a new class to our project named ImageItem.cs and add the following properties to it:

public string Url { get; set; }
public string FileName { get; set; }

11) Now let's implement the OnGetItemsSucceeded method. This method will simply call another method, which runs on the UI thread named ShowItems:

private void OnGetItemsSucceeded(object sender, ClientRequestSucceededEventArgs e)
{
   
this.Dispatcher.BeginInvoke(ShowImages);
}

12) Now let's implement the ShowImages method which builds up a collection of ImageItems and pass it as the DataContext for our application:

private void ShowImages()
{
   
ObservableCollection<ImageItem> images = new ObservableCollection<ImageItem>();
   
foreach (ListItem item in _imagesCollection)
    {
        images.Add(
new ImageItem() { FileName = item["LinkFilename"].ToString(), Url = item["EncodedAbsUrl"].ToString() });
    }
   
this.DataContext = images;
}

13) The only thing left for us to do is implement the scrollControls_MouseLeftButtonDown method that will move our listbox left and right using the arrows:

private void scrollControls_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
   
if ((sender as Image).Name == "nextImageBtn")
    {
        _imageCounter++;
        
if (_imageCounter > imagesListBox.Items.Count - 1)
            _imageCounter--;
    }
   
else
   
{
        _imageCounter--;
       
if (_imageCounter < 0)
            _imageCounter = 0;
    }
    imagesListBox.ScrollIntoView(imagesListBox.Items[_imageCounter]);
}

14) we are done with our Silverlight control!
if you were to upload it to your SharePoint site right now and use the OOTB Silverlight Web part to display it, you would see something like this:

 

While this is probably not the best looking gallery you've ever seen, it's good enough to serve its purpose on our POC.

That’s it for part 1 of this tutorial. In Part 2 we will deal with the ribbon control itself: add a new tab for our gallery, add our control to it and see it in action.

Until then, take care and i look forward to hear your comments here or on Twitter.

Published Sunday, January 16, 2011 10:31 AM by johnnyt

Comments

# Twitter Trackbacks for Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 1 - Johnny's RIA Corner [microsoft.co.il] on Topsy.com

Pingback from  Twitter Trackbacks for                 Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 1 - Johnny's RIA Corner         [microsoft.co.il]        on Topsy.com

# Silverlight and SharePoint 2010 Ribbon Control | www.nalli.net

Pingback from  Silverlight and SharePoint 2010 Ribbon Control | www.nalli.net

# Silverlight and SharePoint 2010 Ribbon Control | www.nalli.net

Pingback from  Silverlight and SharePoint 2010 Ribbon Control | www.nalli.net

# Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 2 - An In Depth Look At The Ribbon Control

Thursday, February 03, 2011 11:15 PM by Johnny's RIA Corner

Welcome to part 2 of the &quot;Fun with Silverlight and SharePoint 2010 Ribbon Control&quot; series.

# Fun with Silverlight and SharePoint 2010 Ribbon Control | allaboutmoss

Pingback from  Fun with Silverlight and SharePoint 2010 Ribbon Control | allaboutmoss

# SharePoint Consultant | SharePoint 2010 Drag and Drop Ribbon Control

Pingback from  SharePoint Consultant  |  SharePoint 2010 Drag and Drop Ribbon Control

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems