Skip to main content

Weblog Ton Stegeman [MVP]

Go Search
Home
  

ODC 2008
If you have a question or suggestion, please contact me through Windows Live Messenger.
My status: .

If I am not online, please send me an e-mail.
Weblog Ton Stegeman [MVP] > Posts > My first Silverlight part 3 – Create the Silverlight web part
My first Silverlight part 3 – Create the Silverlight web part

This is the 3rd part in a small series on Silverlight development for SharePoint. In part 1 I have introduced the Silverlight News web part and showed you how to prepare your server(s) for Silverlight. The 2nd part shows how to create and install the WCF service that will search for the news items. In this part we will create the web part that will host the Silverlight solution. The main task is to host and parameterize the Silverlight control in the page. It also allows users to select a scope and it makes the web part act as a filter consumer. This web part gathers all the information required for the Silverlight application to work properly.

Part 1 - Introduction and preparation
Part 2 - Create the WCF News service
Part 3 - Create the Silverlight web part
Part 4 - Create the Silverlight application

Step 1 – Create a new web part

I added a new class library to my solution and added a new webpart class to the new project. This project needs 2 new references; a reference to Microsoft.SharePoint.dll and a reference to System.Web.Silverlight.dll. The web part has 1 public property, for the scope of the news, and a number of private variables that are needed to host the Silverlight control:

public class NewsWebPart : WebPart, IWebEditable
{
    private ScriptManager _scriptHandler;
    private System.Web.UI.SilverlightControls.Silverlight _silverlightControl = null;

    [Browsable(false),
    Personalizable(PersonalizationScope.Shared)]
    public NewsScope Scope
    {
        get;
        set;
    }

    public NewsWebPart()
    {
    }
}

The NewScope enumeration is defined as:

[DataContract(Namespace = "http://schemas.blackbelts.com/2008/11/news")]
public enum NewsScope : int
{
    [EnumMember()]
    CurrentWeb = 0,

    [EnumMember()]
    CurrentWebAndBelow = 1,

    [EnumMember()]
    SiteCollection = 2
}

Because the  enum will be passed between the Silverlight client and the WCF service, the enum is also decorated with the DataContract attribute.

Step 2 – Create an editor part

Second thing to do is to create an editor part that will let our users select the scope for their news search.

public class NewsWebPartEditor: EditorPart
{
    private const string EMPTYITEM = "EMPTY";
    private RadioButtonList _selectScope;

    public NewsWebPartEditor(string webPartID)
    {
        this.ID = string.Format("SelectWebPropertyEditor{0}", webPartID);
        this.Title = "Silverlight News Options";
    }

    protected override void CreateChildControls()
    {
        Label label = new Label();
        label.Text = "Select a scope:";
        Controls.Add(label);

        _selectScope = new RadioButtonList();
        _selectScope.Items.Add(new ListItem("Current web", NewsScope.CurrentWeb.ToString()));
        _selectScope.Items.Add(new ListItem("Current web and below", NewsScope.CurrentWebAndBelow.ToString()));
        _selectScope.Items.Add(new ListItem("Site Collection", NewsScope.SiteCollection.ToString()));
        Controls.Add(_selectScope);
        base.CreateChildControls();
    }

    public override bool ApplyChanges()
    {
        NewsWebPart webpart = WebPartToEdit as NewsWebPart;
        webpart.Scope = (NewsScope)Enum.Parse(typeof(NewsScope), _selectScope.SelectedValue);
        return true;
    }

    public override void SyncChanges()
    {
        EnsureChildControls();
        NewsWebPart webpart = WebPartToEdit as NewsWebPart;
        _selectScope.SelectedValue = webpart.Scope.ToString();
    }
}

If you want to read more about creating an editor part, read this post I have written about this. Besides creating the editor part, we will need to register it in the NewsWebPart by implementing IWebEditable and implementing CreateEditorParts:

EditorPartCollection IWebEditable.CreateEditorParts()
{
    List<EditorPart> newEditors = new List<EditorPart>();

    EditorPartCollection editors = base.CreateEditorParts();
    foreach (EditorPart part in editors)
        newEditors.Add(part);

    newEditors.Add(new NewsWebPartEditor(this.ID));

    return new EditorPartCollection(newEditors);
}

Step 3 – Initialize and create the controls

In the OnInit, our Silverlight host web part registers a new script manager.

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    _scriptHandler = ScriptManager.GetCurrent(this.Page);
    if (_scriptHandler == null)
    {
        _scriptHandler = new ScriptManager();
        _scriptHandler.ID = string.Format("TST.BlackBelt.Silverlight.News.script_{0}", this.ID);
        this.Controls.Add(_scriptHandler);
    }
}

This scriptmanager is required on the page for the Silverlight control to work properly. In CreateChildControls our web part will create and initialize the Silverlight control. The Source of the Silverlight control points to the xap file that we will create in the next post. Please note that the xap file is deployed to the LAYOUTS folder, which is a folder relative to our current context. The InitParameters property of the silverlight control can be used to initialize the silverlight control. I use the InitParameters to send the title of the web part and the selected scope to the silverlight control. This is important to understand, because once you are in your silverlight control, you are in a totally different request, that knows nothing about SharePoint, web parts or web part properties. Therefore I send all parameter I need in my silverlight control by setting the InitParameters property.

protected override void CreateChildControls()
{
    base.CreateChildControls();

    _silverlightControl = new System.Web.UI.SilverlightControls.Silverlight();
    _silverlightControl.ID = string.Format("TST.BlackBelt.Silverlight.News.xap_{0}", ID);
    _silverlightControl.Source = string.Format("{0}/{1}", SPContext.Current.Web.Url, "_layouts/sbb/TST.BlackBelt.Silverlight.News.xap");

    if (this.Width.Value > 0)
        _silverlightControl.Width = this.Width;
    else
        _silverlightControl.Width = Unit.Pixel(600);

    if (this.Height.Value > 0)
        _silverlightControl.Height = this.Height;
    else
        _silverlightControl.Height = Unit.Pixel(400);
    _silverlightControl.InitParameters = string.Format("WebPartTitle={0}, Scope={1}", this.Title, this.Scope.ToString());
    _silverlightControl.Attributes["Style"] = "z-index:0";
    _silverlightControl.Windowless = true;
    this.Controls.Add(_silverlightControl);

    LiteralControl contentDiv = new LiteralControl("<div id=\"contentDiv\" style=\"position:absolute;z-index:1;border:1px solid black;background-color:white\"></div>");
    this.Controls.Add(contentDiv);
}
 
The last control that is created by our web part and added to the controls collection is a DIV, called the contentDiv. This DIV will be used to render the contents of the news annoucement after the user has selected an item in the interface. See the screenshots in the first article.

Step 4 – Make our web part a filter consumer

Last thing to implement in our web part is the filter consumer. Our web part will accept incoming filter values from filter providers like the out of the box filter web parts, or my List Item Filter or Web Context Filter web parts. To do this, we create a new method and add the ConnectionConsumer attribute. In the SetFilter method, we create a new ConsumerParameter. These parameters can be selected by the user upon connection the web part to a filter provider. In this example web part, we currently only support the Title field. So the webpart can currently only be filtered on the Title field. In the SetFilter web also handle the incoming filter. In this case the filter field and value are added to the InitParameters property of the Silverlight control. Make sure this control is properly initialized by using EnsureChildControls in the SetFilter method. The incoming filter value is added to the initialization parameters for the silverlight control. This controls passes the filter value to the WCF service that we created in the second post. This WCF service processes the filter.

[ConnectionConsumer("filter", "IFilterValues", AllowsMultipleConnections = true)]
public void SetFilter(Microsoft.SharePoint.WebPartPages.IFilterValues filterValues)
{
    if (filterValues != null)
    {
        EnsureChildControls();
        List<Microsoft.SharePoint.WebPartPages.ConsumerParameter> parameters = new List<Microsoft.SharePoint.WebPartPages.ConsumerParameter>();
        parameters.Add(new Microsoft.SharePoint.WebPartPages.ConsumerParameter(
            "Title", 
            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsSingleValue | 
            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsAllValue | 
            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsEmptyValue));
        filterValues.SetConsumerParameters(
            new System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.SharePoint.WebPartPages.ConsumerParameter>(parameters));
        if (filterValues.ParameterValues != null && filterValues.ParameterValues.Count > 0)
        {
            HandleFilter(filterValues.ParameterName, filterValues.ParameterValues[0]);
        }
    }
}

private void HandleFilter(string fieldname, string filter)
{
    _silverlightControl.InitParameters = string.Format("WebPartTitle={0}, Scope={1}, FilterField={2}, FilterValue={3}", this.Title, this.Scope.ToString(), fieldname, filter);
}

If you want to learn more about creating your own filter providers and consumers, you can start by reading this blog post.

Comments

InitParams

Did you set the initparams in a string in the correct format? Should be something like:
_silverlightControl.InitParameters = string.Format("WebPartTitle={0}, Scope={1}", this.Title, this.Scope.ToString());

You can download the full source code here, to check if you are missing something:
http://eoffice.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22471

Ton
Ton Stegeman at 12/4/2009 8:55 AM

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Your city *


Type the name of the city you live in (making it easier to handle spam...)

CurrentDate *

Select the current date (see if this gives me fewer spam...)
Attachments

 Links

  SharePoint Object on CodePlex
  Screencast introducing SharePoint Objects
  Content by Type and Filter Web Parts on CodePlex
  Archive
  Archive (Calendar)

 My Latest Blog Posts

Scripting SharePoint 2007 setup: choices and conceptsUse SHIFT+ENTER to open the menu (new window).
Adventures in Visual Studio 2010: Migrate the Content By Type web part to SharePoint 2010Use SHIFT+ENTER to open the menu (new window).
Register SharePoint themes by using a featureUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010 development on Windows 2008 Server R2 – Getting StartedUse SHIFT+ENTER to open the menu (new window).
New release SharePoint Objects: features and groupsUse SHIFT+ENTER to open the menu (new window).
Constructing the url to the SharePoint Edit Permissions pageUse SHIFT+ENTER to open the menu (new window).
Screencast: introduction to SharePoint ObjectsUse SHIFT+ENTER to open the menu (new window).
SharePoint 2007 and Reporting ServicesUse SHIFT+ENTER to open the menu (new window).
SharePoint Objects – Insight in usage of your SharePoint artifactsUse SHIFT+ENTER to open the menu (new window).
SharePoint 2007 Custom list schema and the Content Query Web PartUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010 Silverlight Client Object Model – ExecuteQuery vs ExecuteQueryAsyncUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010, the Client Object Models and Bing MapsUse SHIFT+ENTER to open the menu (new window).
Having fun with SharePoint 2010, Silverlight 3 and Bing MapsUse SHIFT+ENTER to open the menu (new window).
Connecting TFS 2010 projects to SharePoint sitesUse SHIFT+ENTER to open the menu (new window).
Adding a database to the SharePoint database Server using SPDatabaseUse SHIFT+ENTER to open the menu (new window).