Периодически возникает потребность в создании веб частей, которые могут обмениваться данными. Ниже я приведу пример, как создать такие веб части. Только хочу оговориться, то свой интерфейс стоит использовать, только если Вы будете обмениваться данными со своими собственными веб частями. Если же Вам необходимо с «чужими» веб частями наладить взаимодействие, то следует использовать другие интерфейсы или создать конвертер - http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webparttransformer.aspx .

 

1 – Определите интерфейс

Хотите обмениваться данными – определите передаваемые данные. В моем случае нужно было продемонстрировать передачу текущего пользователя, даты, текста, строки запроса, сайта.

public interface IDataExchange

{

string TextData { get; set; }

DateTime Current { get; set; }

string User { get; set; }

string QueryString { get; set; }

string Site { get; set; }

}

 

2 – Создайте веб часть – поставщик данных

Обратите внимание, что веб часть наследует и реализует интерфейс IDataExchange путем чтения и записи внутренних свойств. Вся основная логика работы собрана в ascx файле.

Также обратите внимание на метод GetData(), который помечен атрибутом ConnectionProvider и возвращает ссылку на реализованный интерфес.

public class ProviderWebPart : WebPart, IDataExchange

{

private const string _ascxPath = @"~/_CONTROLTEMPLATES/SharePointWebParts/ProviderWebPart/ProviderWebPartUserControl.ascx";

 

protected override void CreateChildControls()

{

Control control = Page.LoadControl(_ascxPath);

Controls.Add(control);

}

 

[ConnectionProvider("Текущие данные", "IDataExchange")]

public IDataExchange GetData()

{

return this;

}

 

 

private string _TextData;

string IDataExchange.TextData

{

get

{

return _TextData;

}

set

{

_TextData = value;

}

}

 

private DateTime _Current;

DateTime IDataExchange.Current

{

get

{

return _Current;

}

set

{

_Current = value;

}

}

 

private string _user;

string IDataExchange.User

{

get

{

return _user;

}

set

{

_user = value;

}

}

 

private string _qs;

string IDataExchange.QueryString

{

get

{

return _qs;

}

set

{

_qs = value;

}

}

 

private string _site;

string IDataExchange.Site

{

get

{

return _site;

}

set

{

_site = value;

}

}

}

 

В пользовательском интерфейсе веб части определяется текстовое поле с кнопкой:

<asp:TextBox ID="tbData" runat="server"></asp:TextBox>

<asp:Button ID="btnSend" runat="server" Text="Отправить" onclick="btnSend_Click" />

 

Далее в коде происходит обработка события нажатия на кнопку:

protected void btnSend_Click(object sender, EventArgs e)

{

IDataExchange wp = this.Parent as IDataExchange;

 

wp.Current = DateTime.Now;

wp.QueryString = Request.QueryString.ToString();

wp.Site = SPContext.Current.Web.Title;

wp.TextData = tbData.Text;

wp.User = SPContext.Current.Web.CurrentUser.Name;

}

 

Здесь мы получаем доступ к веб части (ascx файл добавлялся в коллекцию Controls, значит веб часть для него Parent). После этого в интерфейс передаются все необходимые данные. Если соединение между веб частями было установлено, то эти данные попадут во вторую веб часть.

 

3 – Создайте веб часть – потребитель данных

У веб части, которая должна получать данные должен быть метод, принимающий в качестве аргумента параметр нужного нам интерфейса. Метод должен быть помечен атрибутом ConnectionConsumer. Внутри данные просто записываются во внутреннее поле (чтобы можно было обратиться из ascx, но не других сборок).

public class ConsumerWebPart : WebPart

{

private const string _ascxPath = @"~/_CONTROLTEMPLATES/SharePointWebParts/ConsumerWebPart/ConsumerWebPartUserControl.ascx";

 

protected override void CreateChildControls()

{

Control control = Page.LoadControl(_ascxPath);

Controls.Add(control);

}

 

internal IDataExchange _data;

 

[ConnectionConsumer("Текущие данные", "IDataExchange")]

public void ReceiveData(IDataExchange data)

{

_data = data;

}

}

 

В пользовательском интерфейсе ascx в данном случае просто 5 надписей:

<asp:Label ID="Label1" runat="server" Text="Label">

 

А в коде:

protected override void OnPreRender(EventArgs e)

{

base.OnPreRender(e);

 

ConsumerWebPart wp = this.Parent as ConsumerWebPart;

 

if (wp._data!=null)

{

Label1.Text = wp._data.Current.ToString("dd MMMM yyyy г.");

Label2.Text = wp._data.QueryString;

Label3.Text = wp._data.Site;

Label4.Text = wp._data.TextData;

Label5.Text = wp._data.User;

}

}

 

Код написан именно в OnPreRender, поскольку данные отправляются после нажатия на кнопку.

http://msdn.microsoft.com/ru-ru/library/ms178472.aspx

 

4 - Как установить соединение?

Есть 3 способа:

1. Вручную через веб интерфейс.

Добавьте веб части на страницу. В режиме редактирования страницы в меню веб части выберите соединение.

2. В разметке страницы …

…можно добавить и веб части и информацию о соединении. После того, как Вы добавили веб части через веб интерфейс, загляните, что получилось в разметке при помощи SharePoint Designer 2010. Фактически всю разметку можно скопировать, вставить на свою страницу, которая будет развернута в качестве модуля в библиотеке вместе с возможностью.

<%@ Register TagPrefix="WpNs1" Namespace="SharePointWebParts.ConsumerWebPart" Assembly="SharePointWebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2e7821616caba8d3"%>

 

<%@ Register TagPrefix="WpNs0" Namespace="SharePointWebParts.ProviderWebPart" Assembly="SharePointWebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2e7821616caba8d3"%>

 

<WpNs0:ProviderWebPart runat="server" ID="g_88e8e524_5d3d_4a2e_b315_d6879fa7d312" Description="Провайдер" Title="Провайдер" ImportErrorMessage="Не удается импортировать эту веб-часть." __MarkupType="vsattributemarkup" __WebPartId="{5C3C6CF4-9198-455B-B5D5-60F35ABC7689}" WebPart="true" __designer:IsClosed="false"></WpNs0:ProviderWebPart>

 

<WpNs1:ConsumerWebPart runat="server" ID="g_a682363c_7297_4219_a6d0_0efa1cd8c7c5" Description="Потребитель" Title="Потребитель" ImportErrorMessage="Не удается импортировать эту веб-часть." __MarkupType="vsattributemarkup" __WebPartId="{CBEE867B-3E7A-4B50-B5D8-0362A987426E}" WebPart="true" __designer:IsClosed="false"></WpNs1:ConsumerWebPart>

 

<WebPartPages:SPProxyWebPartManager runat="server" ID="__ProxyWebPartManagerForConnections__"><SPWebPartConnections><WebPartPages:SPWebPartConnection ConsumerConnectionPointID="IDataExchange" ConsumerID="g_a682363c_7297_4219_a6d0_0efa1cd8c7c5" ID="c1644797430" ProviderConnectionPointID="IDataExchange" ProviderID="g_88e8e524_5d3d_4a2e_b315_d6879fa7d312"></WebPartPages:SPWebPartConnection>

</SPWebPartConnections></WebPartPages:SPProxyWebPartManager>

 

3. Программно

При помощи класса SPLimitedWebPartManager. Вы должны найти в библиотеке нужную Вам страницу и уже через менеджер сможете добавить веб части, настроить их и соединить между собой. Этот сценарий можно применить в коде активации возможности.

SPFile page;

var wpm = page.GetLimitedWebPartManager(PersonalizationScope.Shared);

 

http://msdn.microsoft.com/en-us/library/ie/microsoft.sharepoint.webpartpages.splimitedwebpartmanager.aspx

 

5 - Что в итоге видит пользователь

В результате из контекста первой веб части были переданы следующие данные:

  1. Текущая дата
  2. Строка запроса (somepage.aspx?q=w)
  3. Название сайта
  4. Текст
  5. Имя пользователя

6 – На практике

В реальной жизни вполне можно сделать, например, веб часть с календарем, при выборе дат в котором в других соединенных веб частях будут выводиться дни рождения сотрудников, встречи и задачи на дату и т.д.

Многие стандартные веб части уже обладают возможностью соединения, кроме того, есть веб части-фильтры:

Для реализации веб частей для соединения со стандартными частями используйте интерфейсы IWebPartField, IWebPartRow.

http://msdn.microsoft.com/en-us/library/a019833t.aspx

 

Исходный код проекта Visual Studio 2010 для SharePoint - SharePointWebParts.zip (76,96 kb)

 

Добро пожаловать на курсы по разработке - http://www.sharepoint2010.ru/page/iw1002.aspx