SharePoint 2007 : Intégration avec Silverlight (Partie 1)

Pour ceux d'entres vous qui n'ont pas eu la possibilité de venir à la Session du Mercredi du Dev sur SharePoint du 5 décembre, je me suis dis que ce serait intéressant de parler un peu plus d'un sujet que j'ai rapidement évoqué en 15 mn : SharePoint et Silverlight.

Lors de cette présentation, je m'etais fixé comme objectif de tester les possibilités de communication de Silverlight 1.0 et 1.1 (la différence est importante) avec SharePoint.

Dans un premier temps, je vous parlerais de l'intégration avec SilverLight 1.1 puis de Silverlight 1.0.

Un petit rappel pour ceux qui ne serait pas familier avec Silverlight (définition de Wikipédia):

« SilverLight (code-name WPF / e) est le nom de code d’une solution navigateur cross-plateforme basée sur XAML qui améliore les présentations à base de contenu riches (2D, animation, dessin vectoriel, vidéo et audio) en complément du code HTML »

«Il est disponible pour Windows XP, Windows Vista et MacOSX, à l'aide de plugins disponibles pour Internet Explorer 6, Internet Explorer 7, Safari d'Apple et Firefox de la Fondation Mozilla. Cependant, il n'est pas encore officiellement disponible sous Linux, et Microsoft n'a pas encore pris de décision à ce sujet. Les utilisateurs de la famille Unix pourront prochainement utiliser un clone de Silverlight 1.1 pour Mono nommé Moonlight.»

Il existe deux versions de Silverlight : 1.0 qui est un «Plug-in portable pour tous navigateurs utilisant JavaScript comme langage de programmation.» et 1.1 avec un «Runtime utilisant une machine virtuelle .NET, qui peut être programmé en C# et autres langages portés sous .NET.»

Pour revenir à notre sujet, le but pour moi était de pouvoir utiliser des exemples donnés sur le site de Silverlight comme la Clock ou Surface tout en faisant le minimum de modifications au XAML pour bien démontrer la simplicité d'intégration à SharePoint qui n'est q'un site ASP.Net comme les autres.

Au final j'ai donc utilisé 3 exemples :

  • Un Hello World à la sauce Silverlight
    Silverlight HelloWorld
  • La Clock
    Silverlight Clock
  • Surface : Charge des images depuis une librairie d'images et permet de les manipuler (agrandissement, rotation, etc...) à la souris
    Silverlight Surface

Chacune de ces démos diffère en terme d'intégration car chacune fait appel à un mécanisme différent:

  • HelloWorld : Charge uniquement un XAML et l'affiche
  • Clock : Charge le XAML et fait appel à une DLL pour faire touner les aiguilles
  • Surface : Charge le XAML, fait appel à une DLL et récupère des informations directement depuis SharePoint

De plus, chacun de ces développements est basé sur l'utilisation d'une Webpart générique, encapsulant tout le travail à faire avec Silverlight:

using System;

using System.Runtime.InteropServices;

using System.Text;

using System.Web.UI;

using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;

 

namespace Mercredi_Dev

{

    [Guid("1642CCC6-D21D-4FA0-8667-9E32F0399621")]

    public class SilverlightWebPart : WebPart

    {

 

        public SilverlightWebPart()

        {

            this.ExportMode = WebPartExportMode.All;

        }

 

        private string _UrlToXaml;

 

        [WebBrowsable(true)]

        [Personalizable(PersonalizationScope.Shared)]

        [WebDisplayName("Url to XAML File")]

        [WebDescription("Enter a Valid Url")]

        public string UrlToXaml

        {

            get

            {

                return _UrlToXaml;

            }

            set

            {

                if (_UrlToXaml == value)

                    return;

                _UrlToXaml = value;

            }

        }

 

        protected override void CreateChildControls()

        {

            base.CreateChildControls();

 

            //Utilisation du ClientScriptManager pour s'assurer

            // que le Silverligt.js (Embedded Ressource) n'est chargé qu'une

            // seule fois même si la webpart est plusieurs fois sur la page

            ClientScriptManager cs = this.Page.ClientScript;

 

            if (cs.IsClientScriptIncludeRegistered("Silverlight"))

                return;

 

            cs.RegisterClientScriptInclude("Silverlight",

                cs.GetWebResourceUrl(this.GetType(), "SilverlightWebPart.Silverlight.js"));

        }

 

        protected override void Render(System.Web.UI.HtmlTextWriter writer)

        {

            base.Render(writer);

 

            string idControl = String.Format("SilverlightControlHost_{0}", this.ID);

            string idXamlControl = String.Format("SilverlightControl_{0}", this.ID);

 

            string width = "100%";

            string height = "480px";

 

            //Plutot que de faire appel au script createSilverlight()

            // j'ai préféré inclure directement le script via la méthode Render

            // il est evident que j'aurais pu faire autrement mais dans le cadre de la démonstration

            // je trouvais que cela permettait de mieux comprendre le fonctionnement

            // de la webpart.

 

            var scriptBuilder = new StringBuilder();

            scriptBuilder.AppendFormat("<div id='{0}' style='Width:{1};Height:{2};'>", idControl, width, height);

            scriptBuilder.Append("        <script type='text/javascript'>");

            scriptBuilder.Append("            Silverlight.createObjectEx({");

            scriptBuilder.AppendFormat("            source: '{0}',", _UrlToXaml);

            scriptBuilder.AppendFormat("            parentElement: document.getElementById('{0}'),", idControl);

            scriptBuilder.AppendFormat("            id: '{0}',", idXamlControl);

            scriptBuilder.Append("                properties: {");

            scriptBuilder.Append("                    width: '100%',");

            scriptBuilder.Append("                    height: '100%',");

            scriptBuilder.Append("                    version: '1.1',");

            scriptBuilder.Append("                    enableHtmlAccess: 'true'");

            scriptBuilder.Append("                },");

            scriptBuilder.Append("                events: {}");

            scriptBuilder.Append("            });");

            scriptBuilder.Append("            document.body.onload = function() {");

            scriptBuilder.AppendFormat("            var silverlightControl = document.getElementById('{0}');", idXamlControl);

            scriptBuilder.Append("                if (silverlightControl)");

            scriptBuilder.Append("                    silverlightControl.focus();");

            scriptBuilder.Append("            }");

            scriptBuilder.Append("      </script>");

            scriptBuilder.Append("  </div>");

 

            writer.Write(scriptBuilder.ToString());

        }

    }

}

Concernant le Silverlight.js, je l'ai placé en Embedded Resource, voici quelque images qui vous permettront de mieux comprendre comment je peux y faire reférence avec le ClientScriptManager

AssemblyInfo Silverlight.js Properties

La propriété UrlToXaml me permet de passer l'url vers le fichier XAML que je souhaite afficher. La webpart s'occupe du reste.

Comme à mon habitude, cette webpart ainsi que les fichiers XAML sont déployés via un fichier Solution et des features.

Arborescence Projet

Voici les fichiers XML necessaires au déploiement de la Webpart et des fichiers XAML :

Feature SilverlightWebPart

feature.xml :

<?xml version="1.0" encoding="utf-8" ?>

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"

        Id="9559f8c8-6a91-4732-a897-716f6eed4945"

        Title="Silverlight Webpart"

        Description="Generic WebPart with a property to fill the XAML file URL"

        Scope="Site"

        Hidden="False"

        Version="1.0.0.0">

  <ElementManifests>

    <ElementManifest Location="elements.xml" />

  </ElementManifests>

</Feature>

elements.xml :

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Url="_catalogs/wp"

          Path="Webpart"

          RootWebOnly="TRUE">

    <File Url="Silverlight.webpart"

          Type="GhostableInLibrary">

      <Property Name="Group" Value="SilverLight" />

      <Property Name="Title" Value="Generic SilverLight WebPart" />

    </File>

  </Module>

</Elements>

Silverlight.webpart :

<webParts>

  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">

    <metaData>

      <type name="Mercredi_Dev.SilverlightWebPart, SilverlightWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXX" />

      <importErrorMessage>Error importing this Web Part!!</importErrorMessage>

    </metaData>

    <data>

      <properties>

        <property name="Title" type="string">Generic SilverLight Web Part</property>

        <property name="UrlToXaml" type="string">http://office12-server/Xaml/HelloWorld.xaml</property>

      </properties>

    </data>

  </webPart>

</webParts>

Feature SilverlightComponents

feature.xml :

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"

        Id="D9A0584F-4BD6-43EC-9D4B-EE7F1B7EA717"

        Title="Silverlight Components"

        Description="Upload the XAML files"

        Scope="Site"

        Hidden="False"

        Version="1.0.0.0">

 

  <ElementManifests>

    <ElementManifest Location="elements.xml" />

  </ElementManifests>

</Feature>

elements.xml :

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Url="XAML"

          Path="XAML"

          RootWebOnly="TRUE">

    <File Url="Clock.xaml"

          Name="Clock.xaml"

          Type="GhostableInLibrary">

    </File>

    <File Url="HelloWorld.xaml"

      Name="HelloWorld.xaml"

      Type="GhostableInLibrary">

    </File>

    <File Url="Surface.xaml"

          Name="Surface.xaml"

          Type="GhostableInLibrary">

    </File>

  </Module>

</Elements>

les fichiers XAML de Clock et Surface sont disponibles aux URLs suivantes : Clock ou Surface

Voici le XAML du fichier Hello World que j'ai utilisé (récupéré sur le net, je ne me rappelle plus de l'auteur, desolé):

<Canvas x:Name="parentCanvas"

        xmlns="http://schemas.microsoft.com/client/2007"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Width="640"

        Height="200"

        Background="White"

        >

    <TextBlock Text="Hello World : Solid brush" FontSize="40" Foreground="#FF0D2764"/>

    <TextBlock Text="Hello World : Gradient brush" FontSize="40" Canvas.Top="80">

        <TextBlock.Foreground>

            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">

                <GradientStop Color="#FF141714" Offset="0"/>

                <GradientStop Color="#FFDD520E" Offset="0.37"/>

                <GradientStop Color="#FF0F2E6A" Offset="0.861"/>

            </LinearGradientBrush>

        </TextBlock.Foreground>

    </TextBlock>

</Canvas>

Voilà tout cela devrait être suffisant pour afficher le HelloWorld.xaml via la Webpart dont je viens de vous parler.

Mais ce ne sera pas suffisant pour les autres fichiers XAML car ils font appel à des DLL, ce qui complique un peu la chose :)

Lors du prochain billet, je vous expliquerai les manipulations à effectuer pour permettre à votre SharePoint d'utiliser ces DLL et comment communiquer avec SharePoint avec Silverlight 1.1.

<Philippe/>

Publié lundi 17 décembre 2007 07:00 par phil
Classé sous , ,
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

About phil

Leader Technique SharePoint chez Winwise, je m'occupe de missions d'expertise autour de WSS 3.0 et MOSS 2007, tout en me tenant au courant de ce qui se fait autour de Asp.net, Silverlight et des technologies Web by Microsoft en général.

Les 10 derniers blogs postés

- La suite ...Proposition de collaboration rédactionnelle entre les communautés de développeurs et Microsoft France par LucasR le il y a 10 heures et 2 minutes

- [Fun] Votre simulateur de vol avec Microsoft ESP par Julien Chable le il y a 15 heures et 45 minutes

- [Best Practices] Customisation du My Site : Comment le modifier en amont et en aval par The Mit's Blog le il y a 16 heures et 59 minutes

- Patrick Tisseghem s'en est allé ... par The Mit's Blog le il y a 17 heures et 43 minutes

- MS AutoCollage par alex# le il y a 18 heures et 29 minutes

- Un grand SharePointeur nous a quitte : Patrick Tisseghem manquera à la communauté ! par RedoBlog - The .NET Gentleman !!! le il y a 18 heures et 54 minutes

- [WPF] Comment charger dynamiquement un fichier XAML qui définit des eventhandler ? par Thomas Lebrun le 09-04-2008, 10:56

- Article sur le filtrage des modèles de site SharePoint par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 09-04-2008, 00:11

- Adopter votre Redo en 3D - Clone Virtuel - avec photosynth par RedoBlog - The .NET Gentleman !!! le 09-04-2008, 00:07

- [Expression Web] Astuce de la Semaine : Mettre en bouton ses macros dans une barre d'outils. par Expression Web & Me le 09-03-2008, 20:48