+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Using Telerik Silverlight controls in Sitefinity

by Georgi Chokov
Here are few guide lines on how to wrap Telerik's Silverlight controls so they can be used in Sitefinity.

In this example I will use the RadCube and the GridView Silverlight controls.

How to:

1. Make sure you have installed Telerik's Silverlight controls and Visual Studio Silverlight Tools.

2. Open a Sitefinity project. Right-Click in the Solution and choose - "Add new Item".

From the items list choose - "Silverlight Application" . I will name the new Silverlight project - "SiApp".

Visual Studio creates the project and adds automatically a two simple pages one .ascx and one .html where the new control is referenced.

3. Create the new Silverlight control layout.

Open the Page.xaml file. Drag&Drop Telerik's RadCube control and set x:Name attribute. Drag&Drop Telerik's RadGridView control within the RadCube and set x:Name attribute and ItemsSource="{Binding}". When this is done your control should look like this:

 

<UserControl xmlns:telerikGridView="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"  xmlns:telerikNavigation="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"  x:Class="SiApp.Page" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > 
    <Grid x:Name="LayoutRoot" Background="White"
        <telerikNavigation:RadCube x:Name="RadCube1" IsRotateOnStart="True" XWidth="400" 
                YWidth="400" ZWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center"
            
            <telerikGridView:RadGridView x:Name="gridView" Height="400" Width="400" ItemsSource="{Binding}"></telerikGridView:RadGridView> 
            
        </telerikNavigation:RadCube> 
    </Grid> 
</UserControl> 
 

Now just save and leave it for now.

4. At this step I will create a simple WebService within Sitefinity that will be used by the Silverlight application to fill the GridView with items.

Right-Click Solution, choose "Add New Item" then select "Web Service", I will name it "GetItemsService.asmx" . In this example I will use Sitefinity's News Module from which I will take the data from. So create a simple Web Method within the service to retrieve the data. Here is how the "GetItemsService" code looks like:

public class GetItemsService : System.Web.Services.WebService 
 
    public GetItemsService() 
    { 
 
        //Uncomment the following line if using designed components  
        //InitializeComponent();  
    } 
 
    [WebMethod] 
    public List<string> GetNewsItems(string provider) 
    { 
        var manager = new NewsManager(provider); 
        var managedContent = manager.Content.GetContent(); 
        var retList = new List<string>(); 
 
        foreach(Telerik.Cms.Engine.IContent item in managedContent) 
        { 
            retList.Add(item.UrlWithExtension); 
        } 
 
        return retList; 
    } 
 

Now you will need to reference the GetItemsService.asmx  from the Silverlight Application. Right-Click References folder of your Silverlight App., choose Add Service Reference, next click the "Discover" button - this will populate the list to the left with all the services contained within the Solution , now choose GetItemsService.asmx and save.

5. Setup Silverlight controls and bind the GridView

Open the Page.xaml code-behind file. In this example I will create two simple methods the first will bind the GridView the second will resize the RadCube. Please have in mind that Silverlight controls are ran on the client machine so it is not possible to control them directly with server side code. The work-around for this is to use JavaScript and hidden fields to call methods and pass values.

A Silverlight control's methods can be called directly from JavaScript functions. In order to do that first make a reference in the Silverlight control to System.Windows.Browser from this point on you can use [ScriptableType] and [ScriptableMember] attributes to expose the class and its members to the JavaScript code. Once this is done you will need "HtmlPage.RegisterScriptableObject" method to add the members to the JavaScript object. Here I have created such a class:

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using Telerik.Windows.Controls; 
using System.Windows.Browser; 
 
 
namespace SiApp 
    [ScriptableType] 
    public partial class Page : UserControl 
    { 
        public Page() 
        { 
            InitializeComponent(); 
            HtmlPage.RegisterScriptableObject("Page"this); 
            this.gridView.AutoGenerateColumns = true
        } 
 
        [ScriptableMember] 
        public void SetCubeSize(int width,int height) 
        { 
            this.RadCube1.Height = height; 
            this.RadCube1.Width = width; 
        } 
 
 
        [ScriptableMember] 
        public void BindCall(string provider) 
        { 
            this.textBox.Text = provider; 
 
            var soapClient = new ServiceReference1.GetItemsServiceSoapClient(); 
            soapClient.GetNewsItemsCompleted += new EventHandler<SiApp.ServiceReference1.GetNewsItemsCompletedEventArgs>(soapClient_GetNewsItemsCompleted); 
            soapClient.GetNewsItemsAsync(provider); 
        } 
 
        private void soapClient_GetNewsItemsCompleted(object sender, SiApp.ServiceReference1.GetNewsItemsCompletedEventArgs e) 
        { 
            var result = e.Result.ToList<string>(); 
            this.textBox.Text = textBox.Text + "::" + result[0]; 
            this.gridView.DataContext = result; 
 
            var soapClient = (ServiceReference1.GetItemsServiceSoap) sender; 
 
        } 
    } 
 

The "SetCubeSize" is used to resize the RadCube and the "BindCall" calls the web service that we previously created and bind the return collection to the GridView.

6. Creating the ASP control that will wrap the newly created Silverlight control.

Right-Click the Solution, choose "Add New Item", select "Web User Control" and save.

Reference the System.Web.Silverlight assembly:

 

<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" 
    TagPrefix="asp" %> 
Reference the newly created Silverlight control:

 

<asp:Silverlight ID="Xaml1" OnPluginLoaded="SetProperties" runat="server" Source="~/ClientBin/SiApp.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />         

Add 3 hidden fields that will be used to pass values from the server to the Silverlight control:

 

<input type="hidden" runat="server" id="providerHidden" /> 
<input type="hidden" runat="server" id="width" /> 
<input type="hidden" runat="server" id="height" /> 

 Now I wrote a simple JavaScript function that will be called when the Silverlight control is done loading:

 

function SetProperties() { 
        var pluginObject = $find("<%=Xaml1.ClientID%>"); 
        var plugin = pluginObject.get_element(); 
 
        //Binds the RadGridView 
        var provName = document.getElementById("<%=providerHidden.ClientID%>"); 
        plugin.Content.Page.BindCall(provName.getAttribute('value')); 
 
        //Resizes the RadCube 
        var getHeight = document.getElementById("<%=height.ClientID%>"); 
        var getWidth = document.getElementById("<%=width.ClientID%>"); 
        plugin.Content.Page.SetCubeSize(getWidth.getAttribute('value'), getHeight.getAttribute('value')); 
    } 

 As you can see I call directly the "BindCall" and "SetCubeSize" methods. This is the simplest way of calling methods within a Silverlight control.

So this is how the .ascx control should look like:

 

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SilverLightCube.ascx.cs" Inherits="SilverLightCube" %> 
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" 
    TagPrefix="asp" %> 
 
<script type="text/javascript"
    function SetProperties() { 
        var pluginObject = $find("<%=Xaml1.ClientID%>"); 
        var plugin = pluginObject.get_element(); 
 
        //Binds the RadGridView 
        var provName = document.getElementById("<%=providerHidden.ClientID%>"); 
        plugin.Content.Page.BindCall(provName.getAttribute('value')); 
 
        //Resizes the RadCube 
        var getHeight = document.getElementById("<%=height.ClientID%>"); 
        var getWidth = document.getElementById("<%=width.ClientID%>"); 
        plugin.Content.Page.SetCubeSize(getWidth.getAttribute('value'), getHeight.getAttribute('value')); 
    } 
</script> 
<asp:Silverlight ID="Xaml1" OnPluginLoaded="SetProperties" runat="server" Source="~/ClientBin/SiApp.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />         
             
            <input type="hidden" runat="server" id="providerHidden" /> 
            <input type="hidden" runat="server" id="width" /> 
            <input type="hidden" runat="server" id="height" /> 
 

 

Now to expose those hidden fields as properties.

Open the .ascx code-behind file and just expose them like this:

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
 
public partial class SilverLightCube : System.Web.UI.UserControl 
    private string provider = "News"
 
    public string Provider { getreturn provider;} set{ provider = value;} } 
    public string Height { getset; } 
    public string Width { getset; } 
 
    protected void Page_Load(object sender, EventArgs e) 
    { 
        var providerHidden = (HtmlInputHidden)this.FindControl("providerHidden"); 
        providerHidden.Value = Provider; 
 
        var heightHidden = (HtmlInputHidden)this.FindControl("height"); 
        var widthHidden = (HtmlInputHidden)this.FindControl("width"); 
 
        heightHidden.Value = Height; 
        widthHidden.Value = Width; 
    } 
 

 

7. Just upload the .ascx control in Sitefinity.

 

This is just an example on how to use Silverlight controls in more efficient way in Sitefinity, of course many other properties can be exposed to make it even more flexible but this example just shows a simple way to do that.

Leave a comment