Tutorial: Creación de elementos web conectables en Windows SharePoint Services
En esta tarea de programación se describe cómo crear dos elementos web de SharePoint conectables: un elemento web que puede consumir un sólo valor de celda y otro elemento web que puede proporcionar un solo valor de celda.
Importante
A partir de Windows SharePoint Services 3.0, la infraestructura de elementos web de SharePoint se basa en la infraestructura de elementos web de Microsoft ASP.NET 2.0 y los elementos web derivados de la clase WebPart son totalmente compatibles con SharePoint, incluido el modelo de conexión de ASP.NET. Siempre que sea posible, debe crear elementos web de ASP.NET y usar el modelo de conexión de ASP.NET para conectar dichos elementos web.
Para obtener más información acerca de cómo elegir la clase base WebPart óptima desde la que hacer la derivación,consulte Desarrollo de elementos web en Windows SharePoint Services. Para obtener más información acerca de los elementos web de ASP.NET y su modelo de conexión, consulte la información general sobre conexiones a elementos web en la documentación de ASP.NET.
Acerca de los elementos web conectables
La infraestructura de elementos web de SharePoint proporciona un conjunto estándar de interfaces, llamadas interfaces de conexión, que permite que los elementos web intercambien información entre sí en tiempo de ejecución. Por ejemplo, el elemento web de lista integrado en Windows SharePoint Services puede proporcionar (enviar) una fila de datos a cualquier otro elemento web que pueda consumir (recibir) dicha fila, como un elemento web que implementa un formulario para mostrar la fila.
Dado que la infraestructura de elementos web proporciona un conjunto estándar de interfaces de conexión, los elementos web conectables pueden ser desarrollados por desarrolladores o compañías totalmente distintos de modo que puedan comunicarse entre sí. Un usuario final con Microsoft Office SharePoint Designer 2007 o un explorador web puede conectar un elemento web compatible con las interfaces de conexión. Esto permite a los usuarios finales crear combinaciones complejas de elementos web mediante una sencilla interfaz de usuario controlada por menús.
Las clases e interfaces de conexión de Windows SharePoint Services se implementan en el espacio de nombres Microsoft.SharePoint.WebPartPages.Communication.
Interfaces de conexión
Las interfaces de conexión son pares de eventos relevantes para un elemento específico, como una fila de una lista. Las interfaces emparejadas establecen un bus de comunicación entre los elementos web que las implementan. Un elemento web conectable genera un evento de interfaz para uno o más elementos conectados de modo que realicen una acción. Las interfaces se emparejan como una relación entre proveedor y consumidor. Los eventos del proveedor se administran en el consumidor y viceversa. En la siguiente tabla se describe brevemente cada par de interfaces de conexión.
Par de interfaces de conexión | Descripción |
---|---|
Interfaces de conexión para proporcionar o consumir un solo elemento de valor, como una celda o un campo. |
|
Interfaces de conexión para proporcionar o consumir una sola fila (o varias filas) de valores. |
|
Interfaces de conexión para proporcionar o consumir una lista completa. |
|
Interfaces de conexión para proporcionar o consumir un valor de filtro. Por ejemplo, el elemento web de lista de SharePoint es compatible con IListProvider, IRowProvider e IFilterConsumer. Dado que IRowProvider se puede conectar a IFilterConsumer, es posible conectar dos listas de SharePoint distintas entre sí. Esto permite que una lista filtre la otra lista conectada. |
|
Las interfaces IParameterIn permiten pasar y recibir cualquier conjunto de parámetros arbitrarios entre los elementos web. Estas interfaces intervienen en una situación en que el elemento web del consumidor es propietario de la lista de parámetros y necesita comunicar esto a otros elementos web. |
|
Las interfaces IParameterOut permiten pasar y recibir cualquier conjunto de parámetros arbitrarios entre los elementos web. Estas interfaces intervienen en una situación en que el elemento web del proveedor es propietario de la lista de parámetros y necesita comunicar esto a otros elementos web. |
Reglas de compatibilidad
Los elementos web sólo se pueden conectar si son compatibles. A continuación se incluyen varias reglas de compatibilidad que la infraestructura de elementos web evalúa al determinar si dos elementos web se pueden conectar. Si los elementos web son incompatibles, el elemento de menú Conexión del explorador se atenúa y aparece información sobre herramientas para explicar el motivo de la incompatibilidad.
Pares opuestos
Una interfaz de conexión sólo se puede conectar con otras interfaces compatibles. La regla de compatibilidad más básica es que las interfaces se deben conectar como pares opuestos o mediante un transformador. La conexión como pares opuestos significa que un elemento web que implementa la interfaz IRowProvider se puede conectar con otro elemento que implementa la interfaz IRowConsumer.
Transformadores
En caso de ser necesario conectar un elemento web a otro elemento que no tenga la misma interfaz, la infraestructura de elementos web proporciona transformadores de interfaz, lo que ayuda a los usuarios a conectar dos interfaces distintas de forma natural y transparente.
Por ejemplo, es posible que un usuario desee conectar una lista de contactos a un visor de imágenes. Sin embargo, la lista de contactos sólo tiene la interfaz IRowProvider y el visor de imágenes sólo tiene la interfaz ICellConsumer. Para solucionar este problema, se proporciona un transformador de interfaz que permite conectar estas dos interfaces entre sí.
En la siguiente tabla se muestran los pares de interfaces que se pueden conectar entre sí mediante un transformador y se especifica si las conexiones requieren Microsoft SharePoint Designer 2007.
Transformador | Conexión en el explorador | Conexión en SharePoint Designer |
---|---|---|
IRowProvider con ICellConsumer |
Sí |
Sí |
IRowProvider con IFilterConsumer |
Sí |
Sí |
IParametersOutProvider con IParametersInConsumer |
No |
Sí |
IRowProvider con IParametersInConsumer |
No |
Sí |
Conexiones entre páginas
Algunas interfaces se pueden conectar a elementos web de otra página. El comportamiento es similar al de un hipervínculo.
Debe saber lo siguiente acerca de las conexiones entre páginas:
Se requiere un editor de páginas web compatible con Windows SharePoint Services, como SharePoint Designer, para establecer conexiones entre páginas. No obstante, una vez establecida la conexión entre páginas, la puede usar cualquier explorador web compatible en tiempo de ejecución.
Tan sólo los elementos web conectables con implementaciones diseñadas para ejecutarse en el servidor (el método CanRunAt tiene un valor ConnectionRunAt de Server o ServerAndClient) pueden establecer conexiones entre páginas. Las conexiones establecidas en el cliente no se permiten para la conexión entre páginas web.
En la siguiente tabla se muestran las interfaces que se pueden conectar entre páginas.
Interfaz de páginas de origen | Interfaz de páginas de destino |
---|---|
IRowProvider |
IFilterConsumer |
IRowProvider |
IParametersInConsumer |
IFilterProvider |
IFilterConsumer |
IParametersOutProvider |
IParametersInConsumer |
IParametersInProvider |
IParametersInConsumer |
Si trabaja con conexiones de elementos web entre páginas, debe hacer lo siguiente:
Pase ConnectionRunAt.Server o ServerAndClient al parámetro runAtOptions del método RegisterInterface.
Pase true al parámetro allowCrossPageConnection del método RegisterInterface.
Implemente el método GetInitEventArgs para proporcionar información específica acerca de los datos pasados mediante la interfaz de conexión.
Conexiones de cliente y servidor
En cualquier momento, los elementos web se pueden ejecutar en el cliente o en el servidor. Algunos elementos web, si están diseñados para este fin, pueden detectar las condiciones en que se están ejecutando y pasar de forma dinámica a ejecutarse en el cliente o en el servidor. Los elementos web sólo se pueden conectar a otros elementos web que se estén ejecutando en la misma ubicación. Por ejemplo, los elementos de servidor sólo se pueden conectar a otros elementos de servidor. Los elementos de servidor no se pueden conectar a elementos de cliente. La cadena de conexiones debe ser homogénea. Si un elemento puede cambiar dinámicamente entre las conexiones de cliente o servidor, la infraestructura de elementos web fijará automáticamente el elemento web para que funcione como un elemento de cliente o servidor según la cadena de elementos web a la que se conecte.
Número máximo de conexiones
Al registrar una interfaz, el número máximo de conexiones a otros elementos web se puede especificar en el parámetro maxConnections del método RegisterInterface. Si se supera el límite de conexiones en un elemento web, no se puede conectar a otros elementos.
Las opciones son 1 o sin límite.
Microsoft.SharePoint.WebPartPages.WebPart.UnlimitedConnections especifica que un elemento web conectable puede aceptar un número ilimitado de conexiones a otro elemento web.
Microsoft.SharePoint.WebPartPages.WebPart.LimitOneConnection especifica que un elemento web conectable puede aceptar tan sólo una conexión.
Conexiones circulares no permitidas
Un elemento web no se puede conectar consigo mismo, ya sea directamente o mediante una cadena de conexiones.
Conexiones de elementos web compartidos y privados
Un elemento web compartido se puede conectar a un elemento web privado si dicho elemento web privado es un consumidor y el elemento web compartido es compatible con un número de conexiones ilimitado.
Flujo de programa
Los elementos web conectados se pasan información entre sí mediante el desencadenamiento de eventos específicos de la interfaz. Si un elemento web implementa una interfaz como ICellProvider, debe reemplazar una serie de métodos. El desencadenamiento de los eventos de la interfaz lo realiza la infraestructura de elementos web mediante la llamada a los métodos reemplazados en los momentos designados. En los siguientes pasos para crear elementos web conectables se definen los métodos que es necesario reemplazar y el código típico que el autor del elemento web debe usar para ello.
Creación de un elemento web que implemente la interfaz ICellProvider
En esta tarea de programación se define el proceso de creación de una clase que implementa todos los métodos y eventos necesarios para una interfaz de conexión que use la interfaz ICellProvider. Para obtener un ejemplo de código completo, consulte los ejemplos de código fuente de ICellProvider e ICellConsumer al final de estos pasos.
Para iniciar esta tarea de programación, realice los pasos que se describen en Tutorial: creación de un elemento web básico de SharePoint además de los pasos necesarios para definir la representación y la lógica del elemento web.
A continuación se incluyen los 11 pasos de alto nivel que debe realizar para implementar una interfaz de conexión para el elemento web:
Cree la clase de interfaz.
Declare los eventos.
Reemplace el método EnsureInterfaces y, a continuación, llame al método RegisterInterface.
Reemplace el método CanRunAt.
Reemplace el método PartCommunicationConnect.
Reemplace el método PartCommunicationInit****.
Reemplace el método PartCommunicationMain.
Reemplace el método GetInitEventArgs.
Implemente los controladores de eventos de la interfaz.
Reemplace el método RenderWebPart.
Implemente los métodos auxiliares.
Paso 1: Crear la clase de interfaz
Cree una clase que implemente una de las interfaces de conexión predefinidas. En este ejemplo, se implementará la interfaz ICellProvider. Para los pasos restantes (2-11), todo el código se incluye en esta clase.
Ejemplo
public class CellProvider : WebPart, ICellProvider
{
// Much code goes here. See steps 2 – 11.
}
Paso 2: Declarar eventos
Declare todos los eventos relevantes para la interfaz de conexión. En esta ubicación, también se declaran las demás variables usadas por el elemento web. Dado que en este caso se trabaja con la interfaz ICellProvider, en el siguiente ejemplo se declaran las variables para los eventos CellProviderInit y CellReady.
Ejemplo
// CellProviderInit Event
public event CellProviderInitEventHandler CellProviderInit;
// CellReady Event
public event CellReadyEventHandler CellReady;
Paso 3: Reemplazar el método EnsureInterfaces y llamar al método RegisterInterface
Reemplace el método EnsureInterfaces. La infraestructura de elementos web llama a este método antes de que se represente el elemento web, momento en el cual el elemento web debe registrar todas sus interfaces mediante la llamada a uno de los dos métodos RegisterInterface.
Ejemplo
public override void EnsureInterfaces()
{
// Register Interfaces (See following section)
}
En el método EnsureInterfaces reemplazado, se notifica a la infraestructura de elementos web sobre las interfaces que se usarán mediante la llamada al método RegisterInterface. Según se indica en el paso 3, el método RegisterInterface se realiza en el método EnsureInterfaces. El método RegisterInterface acepta varios parámetros, los cuales se definen a continuación.
Definición del método
protected InterfaceProperties RegisterInterface(string interfaceName,
string interfaceType,
int maxConnections,
ConnectionRunAt runAtOptions,
object interfaceObject,
string interfaceClientReference,
string menuLabel,
string description)
Nota
Hay un segundo método RegisterInterface disponible, que proporciona un parámetro allowCrossPageConnection adicional para especificar explícitamente si una interfaz es compatible con las conexiones entre páginas. El método RegisterInterface que no incluye este parámetro codifica de forma rígida el establecimiento del parámetro allowCrossPageConnection en true para todas las interfaces de conexión compatibles según las reglas de compatibilidad para la conexión definidas por la infraestructura de elementos web (consulte la sección "Conexiones entre páginas" incluida anteriormente en este tema). El resto de las interfaces de conexión se codifican de forma rígida como false.
Parámetros del método
Parámetro | Descripción |
---|---|
interfaceName |
Propiedad de cadena que es el nombre descriptivo de la interfaz. El nombre descriptivo debe ser único en un elemento. Esta propiedad no puede contener los siguientes caracteres especiales: <, >, &, comillas dobles, comillas simples, coma o punto y coma. |
interfaceType |
Propiedad que representa el tipo de interfaz (IRowProvider, ICellConsumer, etc.). |
maxConnections |
Propiedad que la infraestructura de elementos web puede consultar para determinar cuántas conexiones se pueden establecer en una interfaz concreta. maxConnections es un valor int. Puede tener un valor Microsoft.SharePoint.WebPartPages.WebPart.LimitOneConnection o Microsoft.SharePoint.WebPartPages.WebPart.UnlimitedConnections. |
runAtOptions |
Define dónde se puede ejecutar la interfaz (Client, Server, ClientAndServer, None). |
interfaceObject |
Referencia al objeto real que implementa esta interfaz. |
interfaceClientReference |
Para las conexiones de cliente, interfaceClientReference es una cadena que usa como el identificador para el objeto de cliente que implementa la interfaz. Este identificador debe contener _WPQ_ para garantizar la exclusividad del nombre y puede contener caracteres especiales como (). Se puede usar una cadena vacía si el elemento no es compatible con la comunicación del cliente. La infraestructura de elementos web codifica las comillas dobles como comillas simples.
Nota:
WPQ_ es un token que la infraestructura de elementos web reemplaza por un identificador único si se representa un elemento.
|
menuLabel |
Etiqueta o explicación general de la interfaz. Aparece en la interfaz de usuario del menú de conexión. Se recomienda que la etiqueta de menú empiece por un verbo como "Proporcionar" o "Consumir" para que el usuario que crea la conexión conozca la dirección del flujo de datos. |
description |
Descripción ampliada de la interfaz. |
Ejemplo
InterfaceProperties myCellProviderInterface = RegisterInterface(
"MyCellProviderInterface_WPQ_", //InterfaceName
"ICellProvider", //InterfaceType
WebPart.UnlimitedConnections, //MaxConnections
ConnectionRunAt.ServerAndClient, //RunAtOptions
this, //InterfaceObject
"CellProviderInterface_WPQ_", //InterfaceClientReference
"Provide Value From Text Box", //MenuLabel
"Provides the value entered into the text box."); //Description
Nota
Para detectar las excepciones de los permisos de seguridad de acceso del código, incluya la llamada a RegisterInterface en un bloque try/catch. Para obtener un ejemplo acerca de cómo hacer esto, consulte el tema en que se describe el método RegisterInterface.
Paso 4: Reemplazar el método CanRunAt
Todos los elementos web conectables deben reemplazar el método CanRunAt. La infraestructura de elementos web llama a este método para determinar si un elemento web se puede ejecutar en el servidor, en el cliente o en ambos. El elemento web necesita determinar dónde se puede ejecutar según la configuración actual del cliente del usuario y los demás elementos web a los que está conectado. Los valores que puede devolver son los siguientes valores de la enumeración ConnectionRunAt: Client, Server, ClientAndServer y None. Por ejemplo, un elemento web puede tener dos representaciones distintas: compleja y de nivel inferior. El elemento web puede necesitar un componente ActiveX instalado para la representación compleja. En este caso, el método CanRunAt devuelve Client si el componente ActiveX está instalado o Server si no está instalado.
Ejemplo
public override ConnectionRunAt CanRunAt()
{
// This Web Part can run on both the client and the server
return ConnectionRunAt.ServerAndClient;
}
Paso 5: Reemplazar el método PartCommunicationConnect
Todos los elementos web conectables deben reemplazar el método PartCommunicationConnect. La infraestructura de elementos web llama a este método para notificar al elemento web que se ha conectado y para pasar información relevante, como a qué elemento se ha conectado. Esto tiene lugar en cuanto la infraestructura de elementos web vincula los eventos correspondientes para la conexión. En este método, el autor del elemento web debe realizar un seguimiento de dónde se puede ejecutar la interfaz, crear los controles de UI necesarios y comprobar que la conexión se ha establecido correctamente. Este método tiene varios parámetros, los cuales se definen a continuación.
Definición del método
public override void PartCommunicationConnect (string interfaceName,
WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
Parámetros del método
Parámetro | Descripción |
---|---|
interfaceName |
Nombre descriptivo de la interfaz que se va a conectar. |
connectedPart |
Referencia a otro elemento web con el que se está estableciendo la conexión. Los parámetros connectedPart y connectedInterfaceName proporcionan un método para que el elemento que se conecta identifique el tipo de elemento al que se va a conectar. Esto permite que el elemento web establezca una interacción mejor fundamentada con el otro elemento. Por ejemplo, si el elemento de origen incluye información detallada del elemento de destino, el elemento de origen puede incluirse en el modelo de objetos público del elemento de destino. No obstante, es necesario diseñar estos dos elementos con este propósito para que esto funcione correctamente. Por ejemplo, se podrían diseñar un elemento de diagrama y un elemento de gráfico dinámico para compartir el mismo diseño para un origen de datos común si estuvieran conectados. |
connectedInterfaceName |
Nombre descriptivo de la interfaz en el otro elemento web mediante la que se establece la conexión. |
runAt |
Ubicación en que se puede ejecutar la interfaz. Se trata del cliente o el servidor, y se determina mediante la infraestructura de elementos web en función de varios factores. |
Ejemplo
public override void PartCommunicationConnect(string interfaceName,
WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
{
// Check to see if this is a client-side part
if (runAt == ConnectionRunAt.Client)
{
// This is a client-side part
_runAtClient = true;
return;
}
// Must be a server-side part - create the Web Part's controls
EnsureChildControls();
// Check if this is my particular cell interface
if (interfaceName == "MyCellProviderInterface_WPQ_")
{
// Keep a count of the connections
_cellConnectedCount++;
}
}
Paso 6: Reemplazar el método PartCommunicationInit
Un elemento web conectable puede reemplazar de forma opcional el método PartCommunicationInit. La infraestructura de elementos web llama a este método para permitir que el elemento web desencadene los eventos de inicialización. El elemento web debe desencadenar los eventos que terminan en "Init" (por ejemplo, CellProviderInit).
Los parámetros Init son útiles cuando un elemento web necesita difundir determinada información acerca de sí mismo a otros elementos. Por ejemplo, si un elemento de lista se conecta a un elemento de formulario, el elemento de lista puede difundir sus nombres de campo. A continuación, el elemento de formulario puede representar su interfaz de usuario en función de los nombres de campo del elemento de lista.
Ejemplo
Nota
En el caso de los elementos web del cliente, este evento y su controlador de eventos deben implementarse en el cliente.
public override void PartCommunicationInit()
{
//If the connection wasn't formed then don't send Init event
if(_cellConnectedCount > 0)
{
//If there is a listener, send Init event
if (CellProviderInit != null)
{
//Need to create the args for the CellProviderInit event
CellProviderInitEventArgs cellProviderInitEventArgs = new
CellProviderInitEventArgs();
//Set the FieldName
cellProviderInitEventArgs.FieldName = _cellName;
cellProviderInitEventArgs.FieldDisplayName = _cellDisplayName;
//Fire the CellProviderInit event
CellProviderInit(this, cellProviderInitEventArgs);
}
}
}
Paso 7: Reemplazar el método PartCommunicationMain
Un elemento web conectable puede reemplazar de forma opcional el método PartCommunicationMain. La infraestructura de elementos web llama a este método para permitir que el elemento web desencadene el resto de los eventos de la interfaz (por ejemplo, CellReady). Durante la ejecución del método PartCommunicationMain, se establece la comunicación real de los valores de datos (en contraposición al esquema) entre los elementos web.
Ejemplo
Nota
En el caso de los elementos web del cliente, este evento y su controlador de eventos deben implementarse en el cliente.
public override void PartCommunicationMain()
{
// NOTE: THIS CODE IS SPECIFIC TO EACH AND EVERY WEB PART’S IMPLEMENTATION.
// If the connection wasn't formed then don't send Ready event
if(_cellConnectedCount > 0)
{
// If there is a listener, send CellReady event
if (CellReady != null)
{
// Need to create the args for the CellProviderInit event
CellReadyEventArgs cellReadyEventArgs = new CellReadyEventArgs();
// If user clicked button then send the value
if (_cellClicked)
{
// Set the Cell to the value of the TextBox text
// This is the value that will be sent to the Consumer
cellReadyEventArgs.Cell = _cellInput.Text;
}
else
{
// The user didn't actually click the button
// so just send an empty string to the Consumer
cellReadyEventArgs.Cell = "";
}
// Fire the CellReady event
// The Consumer will then receive the Cell value
CellReady(this, cellReadyEventArgs);
}
}
}
Paso 8: Reemplazar el método GetInitEventArgs
Un elemento web conectable debe reemplazar el método GetInitEventArgs si es necesario. El método GetInitEventArgs sólo es necesario para las interfaces que usan transformadores. Por ejemplo, IRowProvider, ICellConsumer, IFilterConsumer, IParametersOutProvider e IParametersInConsumer son compatibles con los transformadores. Las herramientas de creación de conexiones llaman al método GetInitEventArgs para todos los datos iniciales necesarios para crear la interfaz de usuario del transformador. El método devuelve el objeto InitEventArgs y acepta el nombre de la interfaz.
Por ejemplo, al conectar dos elementos web compatibles con las interfaces IRowProvider e ICellConsumer, el usuario necesita especificar qué campo del elemento web IRowProvider se debe asignar al valor de entrada del elemento web ICellConsumer. Esto se consigue mediante la llamada de la infraestructura de elementos web al método GetInitEventArgs en cada una de las interfaces. Las herramientas de creación de conexiones, como Microsoft Office SharePoint Designer 2007 o el explorador, usan los parámetros Init pasados para crear la interfaz de usuario para el transformador, lo que permite al usuario elegir la asignación de campos.
Definición del método
public override InitEventArgs GetInitEventArgs(string interfaceName)
Parámetros del método
Parámetro | Descripción |
---|---|
interfaceName |
Propiedad de cadena que es el nombre descriptivo de la interfaz. |
Ejemplo
Nota
Este método se puede implementar en el servidor o en el cliente.
Importante
En estos pasos, se ha usado un ejemplo de código para un elemento web que implementa la interfaz ICellProvider. No obstante, la interfaz ICellProvider no debería reemplazar el método GetInitEventArgs porque no puede usar ningún transformador. Para completar este aspecto, al final de esta tarea de programación se incluye un ejemplo de código de CellConsumer.cs, que reemplaza el método GetInitEventArgs.
public override InitEventArgs GetInitEventArgs(string interfaceName)
{
//Check if this is my particular cell interface
if (interfaceName == "MyCellConsumerInterface_WPQ_")
{
EnsureChildControls();
//Need to create the args for the CellConsumerInit event
CellConsumerInitEventArgs cellConsumerInitArgs =
new CellConsumerInitEventArgs();
//Set the FieldName and FieldDisplayName
cellConsumerInitArgs.FieldName = _cellName;
cellConsumerInitArgs.FieldDisplayName = _cellDisplayName;
//return the InitArgs
return(cellConsumerInitArgs);
}
else
{
return(null);
}
}
Paso 9: Implementar controladores de eventos de interfaz
Implemente los controladores de eventos correspondientes según el tipo de interfaz usado. En este ejemplo, la interfaz ICellProvider debe implementar el controlador de eventos CellConsumerInitEventHandler. Este controlador de eventos se debe implementar con independencia de que se usen o no los datos pasados a la interfaz ICellConsumer. El elemento del consumidor desencadena este evento si se ejecuta su método PartCommunicationInit.
Definición del método
public void CellConsumerInit(object sender, CellConsumerInitEventArgs cellConsumerInitEventArgs)
Parámetros del método
Parámetro | Descripción |
---|---|
sender |
Objeto que llama a este método. |
cellConsumerInitEventArgs |
Parámetros pasados por el elemento web del consumidor durante la fase PartCommunicationInit. |
Ejemplo
public void CellConsumerInitEventHandler(object sender, CellConsumerInitEventArgs cellConsumerInitEventArgs)
{
// This is where the Provider part could see what type of "Cell"
// the Consumer was expecting/requesting.
// For this simple code example, this information is not used
// anywhere.
}
Paso 10: Reemplazar el método RenderWebPart
Todos los elementos web deben reemplazar el método RenderWebPart. Los detalles de esta acción son específicos para todos y cada uno de los elementos web. La infraestructura de elementos web llama a este método para representar el elemento web. Para obtener un ejemplo completo, consulte el código fuente CellProvider.cs al final de este tema de tareas de programación. Para abreviar, a continuación se incluye un ejemplo resumido.
Ejemplo
protected override void RenderWebPart(HtmlTextWriter output)
{
// Need to ensure that all of the Web Part's controls are created
EnsureChildControls();
// Render client connection code if the connection is client-side
if (_runAtClient)
{
// Script for client-side rendering
}
else
{
// If connected then display all cell child controls
if (_cellConnectedCount > 0)
{
// Code for server-side rendering
}
else
{
// There wasn't a cell connection formed,
}
}
}
Paso 11: Implementar métodos auxiliares
En esta ubicación del código fuente de ICellProvider, se deben definir todos los métodos auxiliares. A continuación se incluye un resumen. Para obtener un ejemplo completo, consulte el código fuente CellProvider.cs al final de este programa de tareas de programación.
Ejemplo
// Create all controls for this Web Part
protected override void CreateChildControls()
{
//Code for Child Controls
}
// The Button OnClick event handler
private void CellButtonClicked(object sender, EventArgs e)
{
_cellClicked = true; //user clicked button, set to true
}
Par de elementos web de ejemplo que implementan las interfaces ICellProvider e ICellConsumer
Los dos ejemplos de código siguientes muestran cómo crear dos elementos web conectables que implementan las interfaces ICellProvider e ICellConsumer.
Para completar esta tarea de programación, corte y pegue los siguientes ejemplos de código en dos archivos C# del proyecto de elementos web y, a continuación, genere el proyecto.
//--------------------------------------------------------------------
// File : CellProvider.cs
//
// Purpose : A sample connectable Web Part that implements the
// ICellProvider interface.
//
//---------------------------------------------------------------------
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;
using System.Runtime.InteropServices;
namespace ICellDemo
{
/// <summary>
/// The CellProvider Web Part class implementes the ICellProvider
/// interface. Its UI is very basic - it displays a simple text
/// box and button. The CellConsumer Web Part class implements
/// the ICellConsumer interface. When the CellProvider is
/// connected to the CellConsumer on a Web Part Page, the CellProvider
/// can pass the value in its text box to the CellConsumer which displays
/// the value inline.
/// </summary>
///
//Step #1: Implement the Connection Interface (ICellProvider)
public class CellProvider : WebPart, ICellProvider
{
//Step #2: Declare Connection Events
public event CellProviderInitEventHandler CellProviderInit;
public event CellReadyEventHandler CellReady;
//Used to keep track of whether or not the connection will be running client-side
private bool _runAtClient = false;
//Keep a count of ICell connections
private int _cellConnectedCount = 0;
//Web Part UI
private Button _cellButton;
private TextBox _cellInput;
//Cell information
private string _cellName;
private string _cellDisplayName;
//Used to keep track of whether or not the Button in the Web Part was clicked
private bool _cellClicked = false;
//Step #3: EnsureInterfaces
//Notification to the Web Part that is should ensure that all
//its interfaces are registered using RegisterInterface.
public override void EnsureInterfaces()
{
//Registers an interface for the Web Part
RegisterInterface("MyCellProviderInterface_WPQ_", //InterfaceName
InterfaceTypes.ICellProvider, //InterfaceType
WebPart.UnlimitedConnections, //MaxConnections
ConnectionRunAt.ServerAndClient, //RunAtOptions
this, //InterfaceObject
"CellProviderInterface_WPQ_", //InterfaceClientReference
"Provide String from Textbox", //MenuLabel
"Provides a Textbox string"); //Description
}
//Step #4: CanRunAt - called by framework to determine where a part can run.
public override ConnectionRunAt CanRunAt()
{
//This Web Part can run on both the client and the server
return ConnectionRunAt.ServerAndClient;
}
//Step #5: PartCommunicationConnect - Notification to the Web Part that it has been connected.
public override void PartCommunicationConnect(string interfaceName,
WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
{
//Check to see if this is a client-side part
if (runAt == ConnectionRunAt.Client)
{
//This is a client-side part
_runAtClient = true;
return;
}
//Must be a server-side part so need to create the Web Part's controls
EnsureChildControls();
//Check if this is my particular cell interface
if (interfaceName == "MyCellProviderInterface_WPQ_")
{
//Keep a count of the connections
_cellConnectedCount++;
}
}
//Step #6: PartCommunicationInit - Notification to the Web Part that it has been connected.
public override void PartCommunicationInit()
{
//If the connection wasn't actually formed then don't want to send Init event
if(_cellConnectedCount > 0)
{
//If there is a listener, send Init event
if (CellProviderInit != null)
{
//Need to create the args for the CellProviderInit event
CellProviderInitEventArgs cellProviderInitArgs = new CellProviderInitEventArgs();
//Set the FieldName
cellProviderInitArgs.FieldName = _cellName;
cellProviderInitArgs.FieldDisplayName = _cellDisplayName;
//Fire the CellProviderInit event.
CellProviderInit(this, cellProviderInitArgs);
}
}
}
//Step #7: PartCommunicationMain - Called by the framework to allow part to fire any remaining events
public override void PartCommunicationMain()
{
//If the connection wasn't actually formed then don't want to send Ready event
if(_cellConnectedCount > 0)
{
//If there is a listener, send CellReady event
if (CellReady != null)
{
//Need to create the args for the CellProviderInit event
CellReadyEventArgs cellReadyArgs = new CellReadyEventArgs();
//If user clicked button then send the value
if (_cellClicked)
{
//Set the Cell to the value of the TextBox text
//This is the value that will be sent to the Consumer
cellReadyArgs.Cell = _cellInput.Text;
}
else
{
//The user didn't actually click the button
//so just send an empty string to the Consumer
cellReadyArgs.Cell = "";
}
//Fire the CellReady event.
//The Consumer will then receive the Cell value
CellReady(this, cellReadyArgs);
}
}
}
//Step #8: GetInitArgs is not needed in this case. GetInitEventArgs only needs to be
//implemented for interfaces that can participate in a transformer which are
//the following: ICellConsumer, IRowProvider, IFilterConsumer, IParametersOutProvider,
//IParametersInConsumer
//Step #9: Implement CellConsumerInit event handler.
public void CellConsumerInit(object sender, CellConsumerInitEventArgs cellConsumerInitArgs)
{
//This is where the Provider part could see what type of "Cell" the Consumer
//was expecting/requesting.
//For this simple code example, this information is not used anywhere.
}
//Step #10: RenderWebPart - defines Web Part UI and behavior
protected override void RenderWebPart(HtmlTextWriter output)
{
//Need to ensure that all of the Web Part's controls are created
EnsureChildControls();
//Render client connection code if the connection is client-side
if (_runAtClient)
{
//Connected client-side
output.Write(ReplaceTokens("<br><h5>Connected Client-Side</h5><br>\n"
+ "<input type=\"text\" id=\"CellInput_WPQ_\"/>\n"
+ "<button id=\"CellButton_WPQ_\" onclick=\"CellButtonOnClick_WPQ_()\">Fire CellReady</button>\n"
+ "<SCRIPT LANGUAGE=\"JavaScript\">\n"
+ "<!-- \n"
+ " var CellProviderInterface_WPQ_ = new myCellProviderInterface_WPQ_();\n"
+ " function myCellProviderInterface_WPQ_()\n"
+ " {\n"
+ " this.PartCommunicationInit = myInit;\n"
+ " this.PartCommunicationMain = myMain;\n"
+ " this.CellConsumerInit = myCellConsumerInit;\n"
+ " function myInit()\n"
+ " {\n"
+ " var cellProviderInitArgs = new Object();\n"
+ " cellProviderInitArgs.FieldName = \"CellName\";\n"
+ " WPSC.RaiseConnectionEvent(\"MyCellProviderInterface_WPQ_\", \"CellProviderInit\", cellProviderInitArgs);\n"
+ " }\n"
+ " function myMain()\n"
+ " {\n"
+ " var cellReadyArgs = new Object();\n"
+ " cellReadyArgs.Cell = \"\";\n"
+ " WPSC.RaiseConnectionEvent(\"MyCellProviderInterface_WPQ_\", \"CellReady\", cellReadyArgs);\n"
+ " }\n"
+ " function myCellConsumerInit(sender, cellConsumerInitArgs)\n"
+ " {\n"
+ " }\n"
+ " }\n"
+ " function CellButtonOnClick_WPQ_()\n"
+ " {\n"
+ " var cellReadyArgs = new Object();\n"
+ " cellReadyArgs.Cell = document.all(\"CellInput_WPQ_\").value;\n"
+ " WPSC.RaiseConnectionEvent(\"MyCellProviderInterface_WPQ_\", \"CellReady\", cellReadyArgs);\n"
+ " }\n"
+ "//-->\n"
+ "</SCRIPT>"));
}
else //Connected server-side
{
//If connected then display all cell child controls
if (_cellConnectedCount > 0)
{
//Just render some informational text
output.RenderBeginTag(HtmlTextWriterTag.Br);
output.RenderEndTag();
output.RenderBeginTag(HtmlTextWriterTag.H5);
output.Write("Connected Server-Side");
output.RenderEndTag();
output.RenderBeginTag(HtmlTextWriterTag.Br);
output.RenderEndTag();
//Render the TextBox control
_cellInput.RenderControl(output);
//Render the Button
_cellButton.RenderControl(output);
}
else
{
//There wasn't a cell connection formed,
//so just output a message
output.Write("NO CELL INTERFACE CONNECTION");
}
}
}
//Step #11.1 (Supporting Methods): CreateChildControls
protected override void CreateChildControls()
{
//Create the Button
_cellButton = new Button();
_cellButton.ID = "CellButton";
_cellButton.Text = "Fire CellReady";
Controls.Add(_cellButton);
//Create the TextBox
_cellInput = new TextBox();
_cellInput.ID = "CellInput";
Controls.Add(_cellInput);
//Set the Cell information.
//This information will be passed to the Consumer by
//firing the CellProviderInit event.
_cellName = "CellInput";
_cellDisplayName = "CellDisplayInput";
_cellClicked = false; // Initialize to false -- user hasn't clicked yet
_cellButton.Click += new EventHandler(CellButtonClicked); // listen for Button's click event
}
//Step #11.2 (Supporting Methods): CellButtonClicked
// <param name="sender">The Button object</param>
// <param name="e">The Event Arguments</param>
private void CellButtonClicked(object sender, EventArgs e)
{
_cellClicked = true; //user clicked button, set to true
}
}
}
//--------------------------------------------------------------------
// File : CellConsumer.cs
//
// Purpose : A sample connectable Web Part that implements the
// ICellConsumer interface.
//
//---------------------------------------------------------------------
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;
using System.Runtime.InteropServices;
namespace ICellDemo
{
//Step #1: Implement the Connection Interface (ICellConsumer)
public class CellConsumer : WebPart, ICellConsumer
{
//Step #2: Declare Connection events
public event CellConsumerInitEventHandler CellConsumerInit;
//Used to keep track of whether or not the connection will be running client-side
private bool _runAtClient = false;
//Keep a count of ICell connections
private int _cellConnectedCount = 0;
//Web Part UI
private Label _cellLabel;
//Cell information
private string _cellName;
private string _cellDisplayName;
//Step #3: EnsureInterfaces
//Notification to the Web Part that is should ensure that all
//its interfaces are registered using RegisterInterface.
public override void EnsureInterfaces()
{
//Registers an interface for the Web Part.
RegisterInterface("MyCellConsumerInterface_WPQ_", //InterfaceName
InterfaceTypes.ICellConsumer, //InterfaceType
WebPart.UnlimitedConnections, //MaxConnections
ConnectionRunAt.ServerAndClient, //RunAtOptions
this, //InterfaceObject
"CellConsumerInterface_WPQ_", //InterfaceClientReference
"Get String Value", //MenuLabel
"Just a simple ICellConsumer"); //Description
}
//Step #4: CanRunAt - called by framework to determine where a part can run.
public override ConnectionRunAt CanRunAt()
{
//This Web Part can run on both the client and the server
return ConnectionRunAt.ServerAndClient;
}
//Step #5: PartCommunicationConnect - Notification to the Web Part that it has been connected.
public override void PartCommunicationConnect(string interfaceName,
WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
{
//Check to see if this is a client-side part
if (runAt == ConnectionRunAt.Client)
{
//This is a client-side part
_runAtClient = true;
return;
}
//Must be a server-side part so need to create the Web Part's controls
EnsureChildControls();
//Check if this is my particular cell interface
if (interfaceName == "MyCellConsumerInterface_WPQ_")
{
//Keep a count of the connections
_cellConnectedCount++;
}
}
//Step #6: PartCommunicationInit - Notification to the Web Part that it has been connected.
public override void PartCommunicationInit()
{
//If the connection wasn't actually formed then don't want to send Init event
if(_cellConnectedCount > 0)
{
//If there is a listener, send init event
if (CellConsumerInit != null)
{
//Need to create the args for the CellConsumerInit event
CellConsumerInitEventArgs cellConsumerInitArgs = new CellConsumerInitEventArgs();
//Set the FieldNames
cellConsumerInitArgs.FieldName = _cellName;
//Fire the CellConsumerInit event.
//This basically tells the Provider Web Part what type of
//cell the Consuemr is expecting in the CellReady event.
CellConsumerInit(this, cellConsumerInitArgs);
}
}
}
//Step #7: PartCommunicationMain - this method doesn't need to be implemented for the Consumer
//because the Consumer doesn't have any events that need to be fired during this phase.
//Step #8: GetInitArgs - called by the connection authoring tool, e.g., browser or SharePoint Designer
//to get the data required to build the transformer UI.
public override InitEventArgs GetInitEventArgs(string interfaceName)
{
//Check if this is my particular cell interface
if (interfaceName == "MyCellConsumerInterface_WPQ_")
{
EnsureChildControls();
//Need to create the args for the CellConsumerInit event
CellConsumerInitEventArgs cellConsumerInitArgs = new CellConsumerInitEventArgs();
//Set the FieldName
cellConsumerInitArgs.FieldName = _cellName;
cellConsumerInitArgs.FieldDisplayName = _cellDisplayName;
//return the InitArgs
return(cellConsumerInitArgs);
}
else
{
return(null);
}
}
//Step #9.1: Implement CellProviderInit Event Handler.
public void CellProviderInit(object sender, CellProviderInitEventArgs cellProviderInitArgs)
{
//This is where the Consumer part could see what type of "Cell" the Provider
//will be sending.
//For this simple code example, this information is not used anywhere.
}
//Step #9.2: Implement CellReady Event Handler.
//Set label text based on value from the CellProvider Web Part
public void CellReady(object sender, CellReadyEventArgs cellReadyArgs)
{
//Set the label text to the value of the "Cell" that was passed by the Provider
if(cellReadyArgs.Cell != null)
{
_cellLabel.Text = cellReadyArgs.Cell.ToString();
}
}
//Step #10: RenderWebPart - defines Web Part UI and behavior
protected override void RenderWebPart(HtmlTextWriter output)
{
//Need to ensure that all of the Web Part's controls are created
EnsureChildControls();
//Render client connection code if needed
if (_runAtClient)
{
//Connected client-side
string strClientCode = "<br><h5>Connected Client-Side</h5><br>\n";
strClientCode += "<div id=\"ConsumerDiv_WPQ_\"/>\n";
strClientCode += "<SCRIPT LANGUAGE=\"JavaScript\">\n";
strClientCode += "<!-- \n";
strClientCode += " var CellConsumerInterface_WPQ_ = new myCellConsumerInterface_WPQ_();\n";
strClientCode += " function myCellConsumerInterface_WPQ_()\n";
strClientCode += " {\n";
strClientCode += " this.PartCommunicationInit = myInit;\n";
strClientCode += " this.CellProviderInit = myCellProviderInit;\n";
strClientCode += " this.CellReady = myCellReady;\n";
strClientCode += " function myInit()\n";
strClientCode += " {\n";
strClientCode += " var cellConsumerInitArgs = new Object();\n";
strClientCode += " cellConsumerInitArgs.FieldName = \"CellName\";\n";
strClientCode += " WPSC.RaiseConnectionEvent(\"MyCellConsumerInterface_WPQ_\", \"CellConsumerInit\", cellConsumerInitArgs);\n";
strClientCode += " }\n";
strClientCode += " function myCellProviderInit(sender, cellProviderInitArgs)\n";
strClientCode += " {\n";
strClientCode += " }\n";
strClientCode += " function myCellReady(sender, cellReadyArgs)\n";
strClientCode += " {\n";
strClientCode += " document.all('ConsumerDiv_WPQ_').innerHTML = cellReadyArgs.Cell;\n";
strClientCode += " }\n";
strClientCode += " }\n";
strClientCode += "//-->\n";
strClientCode += "</SCRIPT>";
output.Write(ReplaceTokens(strClientCode));
}
else //Connected server-side
{
//If we are connected then display all child controls
if (_cellConnectedCount > 0)
{
//Just render some informational text
output.RenderBeginTag(HtmlTextWriterTag.Br);
output.RenderEndTag();
output.RenderBeginTag(HtmlTextWriterTag.H5);
output.Write("Connected Server-Side");
output.RenderEndTag();
output.RenderBeginTag(HtmlTextWriterTag.Br);
output.RenderEndTag();
//Render the Label control
_cellLabel.RenderControl(output);
}
else
{
//else display no connection message
output.Write("NO CELL INTERFACE CONNECTION");
}
}
}
//Step #11.1 (Supporting Methods): CreateChildControls
protected override void CreateChildControls()
{
//Create the Label
_cellLabel = new Label();
_cellLabel.ID = "CellLabel";
Controls.Add(_cellLabel);
//Set the Cell information.
//This information will be passed to the Provider by
//firing the CellConsumerInit event.
_cellName = "CellInputabc";
_cellDisplayName = "My CellInput";
}
}
}
Para implementar y probar estos elementos web de ejemplo
Realice los pasos que se describen en la sección acerca de la implementación de elementos web de la tarea de programación Tutorial: creación de un elemento web básico de SharePoint; asegúrese de crear un bloque SafeControl y un archivo de definición de elementos web (.dwp) que refleje los valores correspondientes para el ensamblado de elementos web.
Una vez importados los elementos web en una página de elementos web, conecte los elementos web:
Haga clic en Modificar página compartida (o Modificar mi página) y, a continuación, haga clic en Diseñar esta página.
Haga clic en Menú del elemento web en el elemento web del consumidor de celda, seleccione Conexiones, seleccione Consume Cell From y, a continuación, haga clic en el elemento web del proveedor de celda.
En el elemento web del proveedor de celda, escriba un valor en el cuadro de texto y, a continuación, haga clic en el botón Fire CellReady.
Vea también
Otros recursos
Información general sobre conexiones a elementos web de ASP.NET