本文章是由機器翻譯。

資料繫結設計

建立 SharePoint 2010 適用的 Silverlight 4 網頁組件

Paul Stubbs

下載示例代碼

Microsoft SharePoint 2010 提供了一個易於在其中自訂工具的業務協作平臺,組織可以依託這個平臺並實現成長。並且,在構建自訂 SharePoint 解決方案時,最好在前端使用 Silverlight。

Web 部件是大部分 SharePoint 解決方案的核心部分。目前,大部分開發人員都考慮在其 SharePoint 應用程式中使用 Silverlight,在 Web 部件中使用它似乎是一個確鑿無疑的方向,而且 Web 部件是在 SharePoint 中創建 Silverlight 應用程式的最常見方式。但是 Web 部件並非唯一選擇。

您也可以在功能表、導航、對話方塊、頁面配置和母版頁等可在其中放置物件標記的任何位置使用 Silverlight。這賦予了設計人員極大的靈活性,可以創造出如同集成到 SharePoint 中的絕佳體驗。使用此方法,Silverlight 就好像是對 SharePoint 的自然擴展。

不論是 SharePoint 平臺還是 Silverlight,其涉及的廣度和深度都會令開發人員望而生畏。事實上,開發人員通常會將注意力完全放在 SharePoint 上,而設計人員則更熟悉 Silverlight。要構建有用的 SharePoint 應用程式,您必須對這兩種技術都有所瞭解。在本文中,我將向您簡要介紹 Silverlight 與 SharePoint 2010 的集成,並介紹在 SharePoint 解決方案的前端使用 Silverlight 的基礎知識。

Silverlight 和 SharePoint 工作流

配合使用 Silverlight 和 SharePoint 的第一步是使用正確的工具。Visual Studio 和 Expression Blend 被設計為協同工作,通過使用二者,Silverlight 開發人員可以在不打開或安裝 SharePoint 的情況下,使用 SharePoint 中提供的示例資料來創建功能強大的應用程式。同樣,SharePoint 開發人員可以將 Silverlight 應用程式集成到 SharePoint 中,而無需瞭解或深入研究 XAML 代碼。

在本文中,我將介紹如何創建簡單的 Silverlight Web 部件,該部件使用 Silverlight 的 SharePoint 用戶端物件模型來呈現 SharePoint 清單。該應用程式也是 SharePoint 沙箱應用程式,網站集管理員可以安裝和管理該應用程式。該應用程式還可通過 SharePoint Online 標準帳戶運行。

图 1 顯示出最終應用程式在 SharePoint 上運行時的外觀。

圖 1 已完成的 Silverlight/SharePoint 應用程式

SharePoint 示例資料

為了使 Silverlight 和 SharePoint 開發人員獨立工作,Silverlight 開發人員將需要基於 SharePoint 資料的示例資料。這樣,Silverlight 開發人員可以完全自由地創建插入 SharePoint 中後仍可正確工作的應用程式。

Expression Blend 具有多種功能,可支援設計時資料和示例資料。在本示例中,我將使用 XML 格式的示例資料。這意味著 SharePoint 開發人員必須創建表示應用程式將使用的 SharePoint 清單的 XML 檔。您可以按照自己需要的任意形狀建立此示例資料檔案,但是,如果採用與從 SharePoint 返回的形狀相同的形狀建立該檔,則會事半功倍。例如,使用 WCF 資料服務實體和 SharePoint 的 RESTful ListData 服務返回的形狀,與使用 Silverlight 用戶端物件模型返回的資料形狀不同。

在本應用程式中,我將使用 Silverlight 4 中提供的一些新資料綁定功能以及 Silverlight 的 SharePoint 用戶端物件模型。沒有內置的方法可用於生成此示例資料,因此您需要創建一個簡單的主控台應用程式以生成 SharePoint 示例資料。在本例中,我創建了一個使用 Microsoft .NET Framework 用戶端物件模型的 Visual Basic 主控台應用程式,以根據前五個清單項生成 XML 文檔(請參見圖 2)。

圖 2 返回資料 XML 的主控台應用程式

Imports Microsoft.SharePoint.Client
Imports System.Text

Module Module1
  Sub Main()
    Dim context As New _
      ClientContext("http://intranet.contoso.com")
    Dim sampleListItems As ListItemCollection
    Dim sampleList As List = _
      context.Web.Lists.GetByTitle("Contacts")

    Dim qry As New Microsoft.SharePoint.Client.CamlQuery
    qry.ViewXml = "<View><RowLimit>5</RowLimit></View>"
    sampleListItems = sampleList.GetItems(qry)

    context.Load(sampleListItems)

    context.ExecuteQuery()

    'Build the Sample XML Data
    Dim SampleData = _
      <SharePointListItems></SharePointListItems>
    'Iterate through each row using Linq 
    'and XML Literals
    For Each item In sampleListItems
      Dim sampleItem = <ListItem>
        <%= From fieldValue In item.FieldValues _
        Select <<%= fieldValue.Key %>>
        <%= fieldValue.Value %></> %>
        </ListItem>
      SampleData.Add(sampleItem)
    Next
    'Write the file to disk
    System.IO.File.AppendAllText( _
      "C:\SharePointSampleData.xml", _
      SampleData.ToString())
  End Sub
End Module

得到 SharePointSampleData.xml 檔之後,您便可以在 Expression Blend 中將其用作設計時資料來源。

使用示例資料進行設計

得到示例資料 XML 檔後,您便可以打開 Expression Blend 並創建新的 Silverlight 4 應用程式。

在“Data(資料)”面板中,按一下右上角的“Create Sample Data(創建示例資料)”圖示,選擇“Import Sample Data from XML(從 XML 導入示例資料)”,然後流覽到 SharePointSampleData.xml 檔。您還可以選中塊,以在應用程式運行時查看示例資料。否則,您將只能在 Blend 或 Visual Studio 設計器中查看示例資料。

图 3 顯示出 Contacts 清單。用戶端物件模型實際返回的是包含 45 個欄位的字典,因此,要查看完整內容,必須在圖中向下滾動。

圖 3 示例 Contacts 清單

下一步是創建資料繫結欄位表框。在“Data(資料)”面板中,確保設置了“List Mode(清單模式)”圖示。該圖示位於“Data(資料)”面板的左上方。現在,選擇希望在清單方塊中顯示的欄位。在本例中,我選擇了 Title(實際上是名字)和 LastName。將欄位從清單中拖放到設計圖面上。Expression Blend 將創建與欄位進行資料綁定的清單方塊和資料範本。將清單方塊排列到設計圖面的左側,以便為詳細資訊騰出空間。

創建資料綁定詳細資訊同樣非常簡單。從“Data(資料)”面板視窗左上方的圖示中選擇“Details Mode(詳細資訊模式)”。選擇要作為詳細資訊欄位顯示的欄位。將這些欄位拖動到設計圖面上。Expression Blend 將創建綁定到清單方塊中選定專案的每個欄位。如果按 F5 運行應用程式,則將看到用示例資料填充的清單方塊。在清單方塊中更改選定專案時,將會看到右側詳細資訊隨之更改(請參見圖 4)。

圖 4 在 Expression Blend 中處理應用程式

現在,您已經擁有了功能完備的應用程式,並且該應用程式與 SharePoint 示例資料進行了資料綁定。作為 Silverlight 設計人員,您可以繼續測試和優化應用程式,而無需瞭解有關 SharePoint 的任何資訊。在本示例中,我進行了一些設計工作,排列了所有欄位並從 Silverlight 工具包添加了“Sketch(素描)”主題。

Silverlight Web 部件

此時,Silverlight 開發人員可以將專案檔案移交給 SharePoint 開發人員。這樣做的原因是 Expression Blend 和 Visual Studio 共用相同的專案檔案。SharePoint 開發人員在 Visual Studio 2010 中打開專案並能夠查看應用程式的所有部分,因此可以在 Visual Studio 設計器中處理該應用程式(請參見圖 5)。

圖 5 在 Visual Studio 中處理應用程式

SharePoint 開發人員首先要做的是將一個空 SharePoint 專案添加到包含 Silverlight 專案的現有解決方案中。他將使用此 SharePoint 專案部署 Silverlight 應用程式檔案 (.xap) 並創建一個 Silverlight Web 部件,該部件用於承載 Silverlight 應用程式。

與以前構建 SharePoint 解決方案相比,使用 Visual Studio 2010 可以更輕鬆地完成這些任務。按右鍵解決方案,然後選擇“Add New Project(添加新專案)”。流覽到 SharePoint 2010 範本並選擇“Empty SharePoint Project(空白 SharePoint 專案)”。在“New Project(新建專案)”嚮導中,請務必保留預設選擇,以便創建作為沙箱解決方案的專案。這是最佳實踐,可為您提供最靈活和安全的部署選項。Silverlight 還可與沙箱解決方案很好地協作,因為 Silverlight 在用戶端上運行,不受在沙箱中運行的伺服器端代碼的許多限制。

雖然創建順序無關緊要,但最好先創建 Web 部件。這樣,您便可以嵌套將在 Web 部件下部署 Silverlight .xap 檔的模組。這可以保持專案的組織結構良好,並且隨著解決方案的不斷增大易於進行跟蹤。

按右鍵專案並選擇“Add New Item(添加新項)”,以將 Web 部件添加到 SharePoint 專案。從 SharePoint 2010 範本資料夾中選擇 Web 部件。這將在專案中創建新的空 Web 部件。

Web 部件僅由三項組成。第一項是 Elements.xml 檔。這是 SharePoint 解決方案檔,用於說明某個功能中的項。

第二項是 Web 部件定義檔,其副檔名為 .webpart。此檔部署到 SharePoint Web 部件庫中,並定義 Web 部件代碼和 Web 部件的所有屬性。

第三個檔是代碼檔。所有這三個檔均放在專案結構中的資料夾下。

這便是有趣的地方。如果您是從頭開始創建 Web 部件,則在創建新 Web 部件時,添加到專案中的所有檔都是必需的。在本例中,由於 SharePoint 已經附帶 Silverlight Web 部件,因此您無需使用所有自動生成的檔。您要做的就是在此現有 Web 部件上進行構建。為此,您只需將 .webpart 檔指向 Silverlight Web 部件的代碼並包括所有屬性。

創建內置 Silverlight Web 部件 .webpart 檔的副本。實際上可以自動創建。在 SharePoint 中,將 Silverlight Web 部件添加到任意頁面。在設計模式中,按一下 Web 部件的下拉式功能表並選擇“Export(匯出)”。這樣,您便可以創建可添加到專案中的 .webpart 檔副本。現在,只需要更改幾個屬性,例如 Silverlight 應用程式的路徑、標題、說明等。此外,由於您現在使用的是來自內置 Microsoft.SharePoint.dll 的 Web 部件代碼,因此不再需要 Web 部件的 .cs 檔。可以直接刪除此檔。图 6 顯示出 .webpart 檔在被添加到專案後的外觀的一個示例。

圖 6 預設 .webpart 檔摘錄

<webParts>
  <webPart xmlns="https://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.WebPartPages.SilverlightWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>$Resources:core,ImportErrorMessage;
      </importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="HelpUrl" 
                  type="string" />
        <property name="AllowClose" 
                  type="bool">True</property>
        <property name="ExportMode" 
                  type="exportmode">All</property>
        <property name="Hidden" 
                  type="bool">False</property>
        <property name="AllowEdit" 
                  type="bool">True</property>
        <property name="Description" 
                  type="string">Contacts Web Part</property>
        ...
<property name="Height" 
                  type="unit">480px</property>
        <property name="ChromeType" 
                  type="chrometype">None</property>
        <property name="Width" 
                  type="unit">640px</property>
        <property name="Title" 
                  type="string">Contacts Demo</property>
        <property name="ChromeState" 
                  type="chromestate">Normal</property>
        <property name="TitleUrl" 
                  type="string" />
        <property name="Url" 
                  type="string">
        ~site/_catalogs/masterpage/SilverlightApplication1.xap
        </property>
        <property name="WindowlessMode" 
                  type="bool">True</property>
      </properties>
    </data>
  </webPart>
</webParts>

將 Silverlight 部署到 SharePoint

此時,您已擁有了功能完備的 Silverlight 應用程式和承載該 Silverlight 應用程式的 Web 部件。 現在,需要創建 SharePoint 模組以將實際 Silverlight .xap 檔部署到 SharePoint。

Visual Studio 2010 具有內置功能可實現此操作,因此掛接所有內容都相當簡單。 按右鍵 Web 部件資料夾並選擇“Add New Item(添加新項)”。 從 SharePoint 2010 範本中選擇“Module(模組)”範本。

預設情況下將生成一個包含 elements.xml 檔的新模組,與您添加到 Web 部件功能的模組一樣。 該模組中也包含 sample.txt 檔。 請刪除 sample.txt 檔,因為您不需要該檔。

可以通過一種特殊的方法添加對專案中 Silverlight 應用程式的引用。 在解決方案資源管理器中選擇 Module 資料夾並查看屬性。 按一下“Project Output References(專案輸出引用)”屬性以打開“Project Output References(專案輸出引用)”對話方塊。 在該對話方塊中,按一下“Add(添加)”按鈕以添加新引用。 在“Project Name(專案名稱)”下拉式功能表中,選擇 Silverlight 應用程式專案。 將“Deployment Type(部署類型)”設置為“Element File(元素檔)”,然後關閉對話方塊。

現在已添加了對 Silverlight 應用程式的引用。 這與添加標準專案引用的方法相同,Silverlight 專案在 SharePoint 專案之前構建,並且 Silverlight 專案的輸出(.xap 檔)將被覆制到 SharePoint 專案並被內置到 SharePoint 解決方案檔(.wsp 檔)中。

最後一步是設置 Silverlight 應用程式的部署路徑。 這是 .xap 檔將被覆制到的位置以及 Web 部件將從中載入應用程式的位置。

打開 Module 資料夾下的 elements.xml 檔。 將檔元素的 URL 屬性設置為與 .webpart 檔中的 URL 屬性相同。 在本例中,您要將解決方案部署到母版頁庫,因此,請將該值設置為:

~site/_catalogs/masterpage/
  SilverlightApplication1.xap

請注意,路徑開頭的波形符是一個特殊的 SharePoint 萬用字元,用於指示網站的根。

現在,將解決方案部署到 SharePoint 以驗證所有內容是否設置正確。 將 SharePoint 專案設置為預設啟動專案,然後按 F5。 Visual Studio 將構建和打包解決方案。 雖然 Visual Studio 將打開 SharePoint 網站並附加調試器,但您仍需要將 Web 部件添加到頁面。 我發現,開發解決方案時執行此操作的最簡單方法是將 Web 部件添加到新網站頁面。

用戶端物件模型

當所有內容就緒之後,您便可以將 Silverlight 應用程式綁定到實際 SharePoint 資料。 SharePoint 2010 包括 CLR、Silverlight 和 ECMAScript 的用戶端物件模型。 這樣,您就可以使用熟悉的物件模型方便地訪問 SharePoint 資料,如清單和庫。

在此特定示例中,您構建了一個 Silverlight 應用程式,因此需要添加對 Silverlight 用戶端物件模型的引用。 Silverlight 用戶端物件模型由以下兩個檔組成:Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll。 這兩個檔位於 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin\ 中。

在添加引用之後,您便可以編寫代碼以從 Contacts 清單中檢索連絡人。 首先,在 MainPage.xaml.cs 的頂部為 Microsoft.SharePoint.Client 添加 using 語句。 然後,需要定義一對類級別的欄位用於保存返回的結果。 還需要處理頁面載入的事件,用於載入清單資料:

public partial class MainPage : UserControl {
  ClientContext ctx;
  ListItemCollection contactsListItems;

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

  void MainPage_Loaded(
    object sender, RoutedEventArgs e) {
    LoadList();
  }
}

接下來,實現 LoadList 方法以從 SharePoint 檢索資料。 首先,獲取對當前用戶端上下文的引用。 靜態方法 ClientContext.Current 將上下文返回到載入 Web 部件的網站。 然後,您可以調用 GetByTitle 以獲取對 Contacts 清單的引用。 Load 方法會將請求添加到查詢。 然後調用 ExecuteQueryAnsc 進而調用 SharePoint Server:

void LoadList(){
  ctx = ClientContext.Current;

  if (ctx != null) { //null if not in SharePoint
    List contactsList = 
      ctx.Web.Lists.GetByTitle("Contacts");
    contactsListItems =
      contactsList.GetItems(
      CamlQuery.CreateAllItemsQuery());

    ctx.Load(contactsListItems);
    ctx.ExecuteQueryAsync(
      ContactsLoaded, ContactsLoadedFail);
  }
}

對 Silverlight 中伺服器的調用是非同步的。 ExecuteQueryAsync 方法使用兩個回檔委託,一個用於成功結果,一個用於失敗結果。 在 ContactsLoaded 回檔方法中,通過資料綁定將結果綁定到 Silverlight 設計人員在本文開頭部分創建的 XAML。 在成功的回檔中,您需要做的就是將清單方塊的 ItemsSource 屬性設置為由用戶端物件模型返回的連絡人集合。 後臺執行緒上也會發生回檔,因此您將需要更新 Dispatcher 的 BeginInvoke 方法內部的屬性:

// ContactsLoaded
void ContactsLoaded(object sender, 
  ClientRequestSucceededEventArgs args) {
  //call back on the UI thread
  this.Dispatcher.BeginInvoke(() => {
    ContactsListBox.ItemsSource = contactsListItems;
  });
}

失敗的回檔留待讀者實現。

有 ’s 一個您要執行應用程式之前,先做的事:您需要變更 Silverlight 繫結至資料來源的方式。 請記住,我在本文開頭創建了表示來自 SharePoint 的資料的 XML 檔,但此資料並非完全相同,因為 SharePoint 用戶端物件模型實際返回的是字典欄位值的集合。

Silverlight 4 中的一個新功能是能夠綁定到索引子。 這意味著您可以使用鍵值名稱作為綁定命令的字串,對用戶端物件模型返回的字典值進行資料綁定。 遺憾的是,沒有一種很好的方法可用來處理這種複雜的基於字典的示例資料,但使用 Visual Studio 查找和替換工具來回更改綁定也足夠簡單。 例如,您需要將 Text="{Binding Title}"更改為 Text="{Binding Path=FieldValues[Title]}"。 對所有欄位執行此操作。 我已包含規則運算式代碼以在本文的示例代碼中來回切換。

將所有綁定更改為使用 Silverlight 4 索引子綁定後,您便可以運行應用程式。 流覽到您創建的用於承載 Silverlight 應用程式的網站頁面。 其外觀應類似于文章開頭所示的圖 1

動態載入的用戶端物件模型

此時,應用程式已完成,不過我還想演示一點其他內容。 在測試版之後,SharePoint 已發生了一點改動。 使用 Visual Studio 的“Add References(添加引用)”對話方塊流覽檔以創建對 Silverlight 用戶端物件模型的引用時,預設情況下,Visual Studio 將這兩個檔包括在所構建的 .xap 套裝程式中。 這會使 Silverlight 套裝程式額外增加 407KB。

更好的選擇是在運行時動態載入這些程式集。 這樣,流覽器可以緩存這些常用檔,從而減少應用程式的大小和載入時間,同時提高應用程式的性能。

在 SharePoint 測試版之後的版本中,SharePoint 將兩個用戶端物件模型檔打包到名為 Microsoft.SharePoint.Client.xap 的單個 .xap 檔中。 此檔與其他用戶端物件模型檔位於相同的位置,即 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin。 您仍需要添加對用戶端物件模型檔的引用,因為這可以提供所需的 IntelliSense 和編譯支援。 但您將需要在 Silverlight 應用程式的引用資料夾中選擇各個檔,並將“複製本地”屬性設置為 false。 將此屬性設置為 false 可防止 Visual Studio 將這些檔添加到 .xap 套裝程式中。

接下來,您需要添加代碼以動態載入用戶端物件模型程式集。 這是非常通用的代碼,略加修改即可在任何 .xap 套裝程式中的任何 Silverlight 應用程式中使用。 首先更改頁面載入的事件以調用代碼來下載和載入程式集。 在本示例中,將回檔委託傳遞給 LoadList 方法。 這樣,在載入程式集並做好使用準備後,您便可以從 SharePoint 載入清單資料,如下所示:

void MainPage_Loaded(
  object sender, RoutedEventArgs e) {
  LoadClientOM loadClientOM = 
    new LoadClientOM(delegate() { LoadList(); });
  loadClientOM.Run();
}

將新的類檔添加到名為 LoadClientOM.cs 的專案中,並添加圖 7 中所示的代碼。 此代碼使用 WebClient 從 /_layouts/clientbin/Microsoft.SharePoint.Client.xap 下載 .xap 套裝程式。 套裝程式下載完畢後,您需要從套裝程式載入各個程式集。

圖 7 載入 Microsoft.SharePoint.Client.xap

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Resources;
using System.Reflection;

namespace SilverlightApplication1 {
  public class LoadClientOM {
    private bool isDownloaded = false;
    private Action action;

    public LoadClientOM(Action action) {
      this.action = action;
    }

    public void Run() {
      WebClient client = new WebClient();
      client.OpenReadCompleted += 
        new OpenReadCompletedEventHandler(
        client_OpenReadCompleted);
      client.OpenReadAsync(new Uri(
        "/_layouts/clientbin/Microsoft.SharePoint.Client.xap", 
        UriKind.Relative));
    }

    void client_OpenReadCompleted(object sender, 
      OpenReadCompletedEventArgs e) {
      Stream assemblyStream;
      AssemblyPart assemblyPart;

      assemblyStream = Application.GetResourceStream(
        new StreamResourceInfo(e.Result, "application/binary"), 
        new Uri("Microsoft.SharePoint.Client.Silverlight.Runtime.dll", 
        UriKind.Relative)).Stream;
      assemblyPart = new AssemblyPart();
      Assembly b = assemblyPart.Load(assemblyStream);

      assemblyStream = Application.GetResourceStream(
        new StreamResourceInfo(e.Result, "application/binary"), 
        new Uri("Microsoft.SharePoint.Client.Silverlight.dll", 
        UriKind.Relative)).Stream;
      assemblyPart = new AssemblyPart();
      Assembly a = assemblyPart.Load(assemblyStream);

      this.isDownloaded = true;

      if (action != null) {
        action();
      }
    }
  }
}

現在可再次運行應用程式。 您可以看到應用程式外觀完全相同,但現在是在運行時從伺服器動態載入 Silverlight 用戶端物件模型。 在這個簡單的應用程式中難於發現性能上的不同,但在動態載入時應表現出較好的性能。

Paul Stubbs 也是一位 Microsoft 技術推廣專家,主要從事 SharePoint 和 Office、Silverlight 和 Web 2.0 社交網路的資訊工作者開發社區方面的工作。他編寫過三本關於使用 Office、SharePoint 和 Silverlight 開發解決方案的圖書。您可以通過以下網址閱讀他的博客:blogs.msdn.com/b/pstubbs

衷心感謝以下技術專家對本文的審閱: Mike Morton , John Papa Unni Ravindranathan