MatchPoint User Controls

Date: 19.11.2012

In this blog post series I will cover the technical aspects of the new MatchPoint 3.1 User Controls feature. This new feature provides a simple, yet powerful way to build applications in SharePoint.

In will show you how to display data using dynamic rendering logic in a Composite Web Part, how to create re-usable rendering templates, how to use a user control as custom expression variable and how to combine user controls with MatchPoint components such as the Connection and AJAX framework.

"Where comes the name from?" one might ask. The User Control feature is based on the ASP.NET User Controls:

A user control is a kind of composite control that works much like an ASP.NET Web page ? you can add existing Web server controls and markup to a user control, and define properties and methods for the control ...

From the MSDN article ASP.NET User Controls.

User Control Basics

Registration

There are two ways to add or register user controls in MatchPoint:

  1. As File: Create a user control file in <14hive>\Template\Layouts\YourSolution\usercontrols\FileName.ascx and register YourSolution in the MatchPoint Configuration SolutionPaths element.

  2. As Configuration File: Create a new UserControlConfiguration in the MatchPoint configuration dashboard (access via [ctrl]+[m]).

User controls will be available as expression variables where the file leaf name defines the "namespace" and name of the variable. A user control with the file name Acme.Tasks.ItemBodyControl.ascx can be accessed with the expression Acme.Tasks.ItemBodyControl. Such an expression evaluates to an instance of the user control as .NET object. By using the dot notation in the file name, multiple user controls can be grouped together.

User control expression variable in the expression console
Figure 1: User control expression variable in the expression console

Rendering

Since MatchPoint User Controls are in fact ASP.NET User Controls, you can use the ASP.NET rendering features you might know from "aspx" Pages:

ASP.NET controls can be combined with HTML code:

<div>
  <span>Enter your name:</span>
  <asp:TextBox runat="server" ID="UserNameTextBox" />
</div>

C# code can be used in so-called Embedded Code Blocks <% code %>

  • Simple code:

      <div>Time now: <%= DateTime.Now %></div>
    
  • Flow control:

      <div>
        <% if (User.Birthday == DateTime.Today ) %>
          <h1>Happy Birthday <%= Server.HtmlEncode(User.Name) %>!!</h1>
      </div>
    
  • Loop:

      <ul>
        <% for (int i = 0; i < 3; i++) %>
          <li>Item <%= i %></li>
      </ul>
    

Further it is possible to bind data via Data-Binding Expressions <%# binding expression %>:

  • Bind a property:

      <asp:Label Text="<%# DateTime.Now %>" runat="server" />
    
  • Bind a literal text:

      Today is <%# DateTime.Today.DayOfWeek %>
    

MatchPoint Expression Integration

MatchtPoint integrates its Expression Engine features into the user control rendering code. This allows you to call MatchPoint expressions directly in embedded code blocks and binding expressions.

In order to use expressions in user controls, the control class needs to inherit from the TemplateControl class:

<%@ Control Inherits='Colygon.MatchPoint.Core.UserControls.Controls.TemplateControl, Colygon.MatchPoint, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c1901c20b4a53672' %>

Expr(string) Method

The TemplateControl class provides the method protected object Expr(string) that can be called in server code:

<div>
  Welcome <%= Expr("SPHelper.GetCurrentUser().Name.EncodeHtml()") %>
</div>

or

<% if ((bool)Expr("MPUtility.IsInstanceAdministrator()")) %>
  <h1>You are an administrator!</h1>

MP: Prefix in Data-Binding Expressions

Data-binding expression prefixed with MP: will be evaluated as MatchPoint Expression. This allows control value data-binding with MatchPoint Expressions:

<div>
  Welcome <%# MP:SPHelper.GetCurrentUser().Name.EncodeHtml() %>
</div>

or bind a property:

<asp:TextBox 
  Value="<%# MP:SPHelper.GetCurrentListItem().Title %>" 
  runat="server" />

Using the Expression Engine enables you to use features like dynamic properties and dynamic methods directly in user control rendering code. You can for instance directly access a SharePoint list item's fields by their names. Assuming the expression variable DataItem represents an object of type SPListItem <%#MP: DataItem.Author %> returns the creator of the list item:

<div>Created by: <b><%#MP: DataItem.Author %></b></div>

This makes MatchPoint User Controls component a very efficient and powerful tool for rendering data returned by MatchPoint Data Providers.

Rendering Templates

The Composite Web Part transformer UserControlTransformer is used to reference a control as rendering template. The configuration of this transformer takes an expression that is expected to evaluate to an object of type System.Web.Control.

A user control named My.Fancy.Control.ascx can be referenced with the expression My.Fancy.Control, since the user control expression evaluates to an instance of an ASP.NET control.

A Composite Web Part transformer renders (or transforms) a result set returned by the configured Data Provider. In case of the User Control Transformer this is done by the referenced user control.

In order to render multiple rows we need a way to specify a template that is used to render a row. This can be done with the MatchPoint Repeater Control. Like the ASP.NET repeater the MatchPoint Repeater Control provides a template for the header, row and footer:

<mp:Repeater runat="server">
  <HeaderTemplate>
    <ul>
  </HeaderTemplate>
  <RowTemplate>
    <li>Item</li>
  </RowTemplate>
  <FooterTemplate>
    </ul>
  <FooterTemplate>
</mp:Repeater>

As in the Pattern Transformer, the current row can be accessed with the expression variable DataItem. Assuming the following template renders a SharePoint news list:

<mp:Repeater runat="server">
  <RowTemplate>
    <div>
      <h1><%# MP:DataItem.Title.EncodeHtml() %></h1>
      <p><%# MP:DataItem.Body %></p>
    </div>
  </RowTemplate>
</mp:Repeater>

Please check the download section at the end of the post for complete code samples.

We can use server code in the repeater templates as well. Lets say we want to render the first news item in a h1 tag and all others in a h2 tag:

<script runat="server">
  // This defines a private field in the control class.
  // This field can be accessed later in the render code.
  private bool isFirstItem = true;
</script>

<mp:Repeater runat="server">
  <RowTemplate>
    <div>
      <!-- check on the private field isFirstItem; render 
           h1 tag and set the private field to false -->
      <% if (isFirstItem) { %>
        <h1><%# MP:DataItem.Title.EncodeHtml() %></h1>
      <% isFirstItem = false; %>
      <% } else { %>
        <h2><%# MP:DataItem.Title.EncodeHtml() %></h2>
      <% } %>

      <p><%# MP:DataItem.Body %></p>
    </div>
  </RowTemplate>
</mp:Repeater>

In cases where the render logic is dependent on the result item, the method Expr can be used to access the DataItem. In the next snippet the image of a news post from the previous example is rendered if the property Image is set:

<RowTemplate>
  <div>
    <!-- ... -->

    <% if ((bool)Expr("DataItem.Image != null")) { %>
      <img src='<%# MP:DataItem.Image %>' >
    <% } %>

    <p><%# MP:DataItem.Body %></p>
  </div>
</RowTemplate>

The User Control Transformer detects column names used in MatchPoint binding expressions (the columns 'Title', 'Body' and 'ImageUrl' in the example above). These columns will be automatically included in the query performed by the specified data provider. This mechanism is only available in binding expressions (<#MP:expr %>) and not when evaluating expression via the method Expr.

The method TemplateControl.AddRequiredColumns can be overridden to include additional column names:

<script runat="server">
  public override AddRequiredColumns(string varName, 
    RequiredColumnCollection columns)
  {
    base.AddRequiredColumns(varName, columns);
    columns.Add("MyImportantColumn");
  }
</script>

The attentive reader already spotted how to create Expression Variables with user controls. I will cover the Expression Variable implementation details in the next posts of the series. Further, I will show you how to combine the Connection Framework with the User Control Transformer to create dynamic data views and how to re-use rendering code in user controls.

results matching ""

    No results matching ""