Tutorial: Creación de elementos web conectables en SharePoint Foundation

Última modificación: jueves, 29 de septiembre de 2011

Hace referencia a: SharePoint Foundation 2010

En este artículo
Acerca de los elementos web conectables
Creación de un elemento web que implemente la interfaz ICellProvider
Paso 1: Crear la clase de interfaz
Paso 2: Declarar eventos
Paso 3: Invalidar el método EnsureInterfaces y llamar al método RegisterInterface
Paso 4: Invalidar el método CanRunAt
Paso 5: Invalidar el método PartCommunicationConnect
Paso 6: Invalidar el método PartCommunicationInit
Paso 7: Invalidar el método PartCommunicationMain
Paso 8: Invalidar el método GetInitEventArgs
Paso 9: Implementar controladores de eventos de interfaz
Paso 10: Invalidar el método RenderWebPart
Paso 11: Implementar métodos auxiliares
Par de elementos web de ejemplo que implementan las interfaces ICellProvider e ICellConsumer

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.

Nota importanteImportante

La infraestructura de elementos web de Microsoft SharePoint Foundation se basa en la infraestructura de elementos web de Microsoft ASP.NET y los elementos web derivados de la clase de ASP.NETWebPart 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 los elementos web.

Para obtener más información acerca de cómo elegir la clase base WebPart óptima para derivar elementos web, vea 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, vea la introducción a las 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 permiten que los elementos web intercambien información entre sí en tiempo de ejecución. Por ejemplo, el elemento web de lista integrado en SharePoint Foundation 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 programadores o compañías totalmente distintos de modo que puedan comunicarse entre sí. Un usuario final con Microsoft SharePoint Designer 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 interfaces y clases de conexión de SharePoint Foundation 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

ICellProvider, ICellConsumer

Interfaces de conexión para proporcionar o consumir un solo elemento de valor, como una celda o un campo.

IRowProvider, IRowConsumer

Interfaces de conexión para proporcionar o consumir una sola fila (o varias filas) de valores.

IListProvider, IListConsumer

Interfaces de conexión para proporcionar o consumir una lista completa.

IFilterProvider, IFilterConsumer

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.

IParametersInProvider, IParametersInConsumer

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.

IParametersOutProvider, IParametersOutConsumer

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 solo se pueden conectar si son compatibles. A continuación se incluyen varias reglas de compatibilidad que la infraestructura de elementos web evalúa para determinar si dos elementos web se pueden conectar. Si los elementos web son incompatibles, el elemento de menú Conexión del explorador se deshabilita 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 2010.

Transformador

Conexión

en el explorador

Conexión en SharePoint Designer 2010

IRowProvider con ICellConsumer

IRowProvider con IFilterConsumer

IParametersOutProvider con IParametersInConsumer

No

IRowProvider con IParametersInConsumer

No

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 SharePoint Foundation, como SharePoint Designer 2010, 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:

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.

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 invalidar 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.

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:

  1. Cree la clase de interfaz.

  2. Declare los eventos.

  3. Invalide el método EnsureInterfaces y después llame al método RegisterInterface.

  4. Invalide el método CanRunAt.

  5. Invalide el método PartCommunicationConnect.

  6. Invalide el método PartCommunicationInit.

  7. Invalide el método PartCommunicationMain.

  8. Invalide el método GetInitEventArgs.

  9. Implemente los controladores de eventos de la interfaz.

  10. Invalide el método RenderWebPart.

  11. 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.
}
Public Class CellProvider
    Inherits WebPart
    Implements ICellProvider

    ' Much code goes here. See steps 2 – 11.
End Class

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;
' CellProviderInit Event

Public Event CellProviderInit As CellProviderInitEventHandler

' CellReady Event

Public Event CellReady As CellReadyEventHandler

Paso 3: Invalidar el método EnsureInterfaces y llamar al método RegisterInterface

Invalide 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) 

}
Public Overrides Sub EnsureInterfaces()
   ' Register Interfaces      (See following section) 

End Sub

En el método EnsureInterfaces invalidado, 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)
 Protected Function RegisterInterface(ByVal interfaceName As String,
                                         ByVal interfaceType As String,
                                         ByVal maxConnections As Integer,
                                          ByVal runAtOptions As ConnectionRunAt,
                                          ByVal interfaceObject As Object,
                                          ByVal interfaceClientReference As String,
                                          ByVal menuLabel As String,
                                          ByVal description As String) As InterfaceProperties

End Function

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 WebPart.LimitOneConnection o 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.

NotaNota
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
Dim myCellProviderInterface As InterfaceProperties = RegisterInterface("MyCellProviderInterface_WPQ_", "ICellProvider", WebPart.UnlimitedConnections, ConnectionRunAt.ServerAndClient, Me, "CellProviderInterface_WPQ_", "Provide Value From Text Box", "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: Invalidar el método CanRunAt

Todos los elementos web conectables deben invalidar 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;
}
public override ConnectionRunAt CanRunAt()
{
   // This Web Part can run on both the client and the server
   return ConnectionRunAt.ServerAndClient;
}

Paso 5: Invalidar el método PartCommunicationConnect

Todos los elementos web conectables deben invalidar 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)
Public Overrides Sub PartCommunicationConnect(ByVal interfaceName As String, ByVal connectedPart As WebPart, ByVal connectedInterfaceName As String, ByVal runAt As ConnectionRunAt)

End Sub

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++;
   }
}
Public Overrides Sub PartCommunicationConnect(ByVal interfaceName As String, ByVal connectedPart As WebPart, ByVal connectedInterfaceName As String, ByVal runAt As ConnectionRunAt)
   ' Check to see if this is a client-side part
   If runAt Is ConnectionRunAt.Client Then
       ' This is a client-side part
       _runAtClient = True
        Return
   End If

   ' 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_" Then
      ' Keep a count of the connections
      _cellConnectedCount += 1
   End If
End Sub

Paso 6: Invalidar el método PartCommunicationInit

Un elemento web conectable puede invalidar 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);
      }
   }
}
Public Overrides Sub PartCommunicationInit()
    'If the connection wasn't formed then don't send Init event
    If _cellConnectedCount > 0 Then
        'If there is a listener, send Init event
        If CellProviderInit IsNot Nothing Then
            'Need to create the args for the CellProviderInit event
            Dim cellProviderInitEventArgs As New CellProviderInitEventArgs()

            'Set the FieldName
            cellProviderInitEventArgs.FieldName = _cellName
            cellProviderInitEventArgs.FieldDisplayName = _cellDisplayName

            'Fire the CellProviderInit event
            CellProviderInit(Me, cellProviderInitEventArgs)
        End If
    End If
End Sub

Paso 7: Invalidar el método PartCommunicationMain

Un elemento web conectable puede invalidar 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);
      }
   }
}
 Public Overrides Sub 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 Then
        ' If there is a listener, send CellReady event
        If CellReady IsNot Nothing Then
            ' Need to create the args for the CellProviderInit event
            Dim cellReadyEventArgs As New CellReadyEventArgs()

            ' If user clicked button then send the value
            If _cellClicked Then
                ' 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 = ""
            End If

            ' Fire the CellReady event
            ' The Consumer will then receive the Cell value
            CellReady(Me, cellReadyEventArgs)
        End If
    End If
End Sub

Paso 8: Invalidar el método GetInitEventArgs

Un elemento web conectable debe invalidar 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 SharePoint Designer 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)
Public Overrides Function GetInitEventArgs(ByVal interfaceName As String) As InitEventArgs
End Function

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.

Nota importanteImportante

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 invalida 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);
   }
}
Public Overrides Function GetInitEventArgs(ByVal interfaceName As String) As InitEventArgs
    'Check if this is my particular cell interface
    If interfaceName = "MyCellConsumerInterface_WPQ_" Then
        EnsureChildControls()

        'Need to create the args for the CellConsumerInit event
        Dim cellConsumerInitArgs As New CellConsumerInitEventArgs()

        'Set the FieldName and FieldDisplayName
        cellConsumerInitArgs.FieldName = _cellName
        cellConsumerInitArgs.FieldDisplayName = _cellDisplayName

        'return the InitArgs
        Return cellConsumerInitArgs
    Else
        Return Nothing
    End If
End Function

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.

}
Public Sub CellConsumerInitEventHandler(ByVal sender As Object, ByVal cellConsumerInitEventArgs As 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.

End Sub

Paso 10: Invalidar el método RenderWebPart

Todos los elementos web deben invalidar 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, vea 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,
      }
   }
}
Protected Overrides Sub RenderWebPart(ByVal output As HtmlTextWriter)
    ' 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 Then
        ' Script for client-side rendering
    Else
        ' If connected then display all cell child controls
        If _cellConnectedCount > 0 Then
            ' Code for server-side rendering

        Else
            ' There wasn't a cell connection formed,
        End If
    End If
End Sub

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
}
' Create all controls for this Web Part
Protected Overrides Sub CreateChildControls()
   'Code for Child Controls
End Sub

' The Button OnClick event handler
Private Sub CellButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
   _cellClicked = True 'user clicked button, set to true
End Sub

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 : CellProvider.cs
'
' Purpose : A sample connectable Web Part that implements the 
'          ICellProvider interface.
'
'---------------------------------------------------------------------

Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Imports Microsoft.SharePoint.WebPartPages
Imports Microsoft.SharePoint.WebPartPages.Communication
Imports 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
        Inherits WebPart
        Implements ICellProvider
        'Step #2: Declare Connection Events
        Public Event CellProviderInit As CellProviderInitEventHandler
        Public Event CellReady As CellReadyEventHandler

        'Used to keep track of whether or not the connection will be running client-side
        Private _runAtClient As Boolean = False

        'Keep a count of ICell connections
        Private _cellConnectedCount As Integer = 0

        'Web Part UI
        Private _cellButton As Button
        Private _cellInput As TextBox

        'Cell information
        Private _cellName As String
        Private _cellDisplayName As String

        'Used to keep track of whether or not the Button in the Web Part was clicked
        Private _cellClicked As Boolean = False


        'Step #3: EnsureInterfaces
        'Notification to the Web Part that is should ensure that all
        'its interfaces are registered using RegisterInterface.
        Public Overrides Sub EnsureInterfaces()
            'Registers an interface for the Web Part
            RegisterInterface("MyCellProviderInterface_WPQ_", InterfaceTypes.ICellProvider, WebPart.UnlimitedConnections, ConnectionRunAt.ServerAndClient, Me, "CellProviderInterface_WPQ_", "Provide String from Textbox", "Provides a Textbox string") 'Description - MenuLabel - InterfaceClientReference - InterfaceObject - RunAtOptions - MaxConnections - InterfaceType - InterfaceName
        End Sub


        'Step #4: CanRunAt - called by framework to determine where a part can run.
        Public Overrides Function CanRunAt() As ConnectionRunAt
            'This Web Part can run on both the client and the server
            Return ConnectionRunAt.ServerAndClient
        End Function

        'Step #5: PartCommunicationConnect - Notification to the Web Part that it has been connected.
        Public Overrides Sub PartCommunicationConnect(ByVal interfaceName As String, ByVal connectedPart As WebPart, ByVal connectedInterfaceName As String, ByVal runAt As ConnectionRunAt)
            'Check to see if this is a client-side part
            If runAt Is ConnectionRunAt.Client Then
                'This is a client-side part
                _runAtClient = True
                Return
            End If

            '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_" Then
                'Keep a count of the connections
                _cellConnectedCount += 1
            End If
        End Sub

        'Step #6: PartCommunicationInit - Notification to the Web Part that it has been connected.
        Public Overrides Sub PartCommunicationInit()
            'If the connection wasn't actually formed then don't want to send Init event
            If _cellConnectedCount > 0 Then
                'If there is a listener, send Init event
                If CellProviderInitEvent IsNot Nothing Then
                    'Need to create the args for the CellProviderInit event
                    Dim cellProviderInitArgs As New CellProviderInitEventArgs()

                    'Set the FieldName
                    cellProviderInitArgs.FieldName = _cellName
                    cellProviderInitArgs.FieldDisplayName = _cellDisplayName

                    'Fire the CellProviderInit event.
                    RaiseEvent CellProviderInit(Me, cellProviderInitArgs)
                End If
            End If
        End Sub

        'Step #7: PartCommunicationMain - Called by the framework to allow part to fire any remaining events
        Public Overrides Sub PartCommunicationMain()
            'If the connection wasn't actually formed then don't want to send Ready event
            If _cellConnectedCount > 0 Then
                'If there is a listener, send CellReady event
                If CellReadyEvent IsNot Nothing Then
                    'Need to create the args for the CellProviderInit event
                    Dim cellReadyArgs As New CellReadyEventArgs()

                    'If user clicked button then send the value
                    If _cellClicked Then
                        '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 = ""
                    End If


                    'Fire the CellReady event.
                    'The Consumer will then receive the Cell value
                    RaiseEvent CellReady(Me, cellReadyArgs)
                End If
            End If
        End Sub

        '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 Sub CellConsumerInit(ByVal sender As Object, ByVal cellConsumerInitArgs As 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.
        End Sub

        'Step #10: RenderWebPart - defines Web Part UI and behavior
        Protected Overrides Sub RenderWebPart(ByVal output As HtmlTextWriter)
            '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 Then
                'Connected client-side
                output.Write(ReplaceTokens("<br><h5>Connected Client-Side</h5><br>" & vbLf & "<input type=""text"" id=""CellInput_WPQ_""/>" & vbLf & "<button id=""CellButton_WPQ_"" onclick=""CellButtonOnClick_WPQ_()"">Fire CellReady</button>" & vbLf & "<SCRIPT LANGUAGE=""JavaScript"">" & vbLf & "<!-- " & vbLf & "    var CellProviderInterface_WPQ_ = new myCellProviderInterface_WPQ_();" & vbLf & "    function myCellProviderInterface_WPQ_()" & vbLf & "    {" & vbLf & "        this.PartCommunicationInit = myInit;" & vbLf & "        this.PartCommunicationMain = myMain;" & vbLf & "        this.CellConsumerInit = myCellConsumerInit;" & vbLf & "        function myInit()" & vbLf & "        {" & vbLf & "            var cellProviderInitArgs = new Object();" & vbLf & "            cellProviderInitArgs.FieldName = ""CellName"";" & vbLf & "            WPSC.RaiseConnectionEvent(""MyCellProviderInterface_WPQ_"", ""CellProviderInit"", cellProviderInitArgs);" & vbLf & "        }" & vbLf & "        function myMain()" & vbLf & "        {" & vbLf & "            var cellReadyArgs = new Object();" & vbLf & "            cellReadyArgs.Cell = """";" & vbLf & "            WPSC.RaiseConnectionEvent(""MyCellProviderInterface_WPQ_"", ""CellReady"", cellReadyArgs);" & vbLf & "        }" & vbLf & "        function myCellConsumerInit(sender, cellConsumerInitArgs)" & vbLf & "        {" & vbLf & "        }" & vbLf & "    }" & vbLf & "    function CellButtonOnClick_WPQ_()" & vbLf & "    {" & vbLf & "        var cellReadyArgs = new Object();" & vbLf & "        cellReadyArgs.Cell = document.all(""CellInput_WPQ_"").value;" & vbLf & "        WPSC.RaiseConnectionEvent(""MyCellProviderInterface_WPQ_"", ""CellReady"", cellReadyArgs);" & vbLf & "    }" & vbLf & "//-->" & vbLf & "</SCRIPT>"))
            Else 'Connected server-side
                'If connected then display all cell child controls
                If _cellConnectedCount > 0 Then
                    '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")
                End If
            End If
        End Sub

        'Step #11.1 (Supporting Methods): CreateChildControls
        Protected Overrides Sub 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
            AddHandler _cellButton.Click, AddressOf CellButtonClicked ' listen for Button's click event
        End Sub

        'Step #11.2 (Supporting Methods): CellButtonClicked
        ' <param name="sender">The Button object</param>
        ' <param name="e">The Event Arguments</param>
        Private Sub CellButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
            _cellClicked = True 'user clicked button, set to true
        End Sub
    End Class
End Namespace
//--------------------------------------------------------------------
// 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";
      }
   }
}
'--------------------------------------------------------------------
' File : CellConsumer.cs
'
' Purpose : A sample connectable Web Part that implements the 
'          ICellConsumer interface.
'
'---------------------------------------------------------------------
Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Imports Microsoft.SharePoint.WebPartPages
Imports Microsoft.SharePoint.WebPartPages.Communication
Imports System.Runtime.InteropServices

Namespace ICellDemo

    'Step #1: Implement the Connection Interface (ICellConsumer)
    Public Class CellConsumer
        Inherits WebPart
        Implements ICellConsumer

        'Step #2: Declare Connection events
        Public Event CellConsumerInit As CellConsumerInitEventHandler

        'Used to keep track of whether or not the connection will be running client-side
        Private _runAtClient As Boolean = False

        'Keep a count of ICell connections
        Private _cellConnectedCount As Integer = 0

        'Web Part UI
        Private _cellLabel As Label

        'Cell information
        Private _cellName As String
        Private _cellDisplayName As String

        'Step #3: EnsureInterfaces
        'Notification to the Web Part that is should ensure that all
        'its interfaces are registered using RegisterInterface.
        Public Overrides Sub EnsureInterfaces()
            'Registers an interface for the Web Part.
            RegisterInterface("MyCellConsumerInterface_WPQ_", InterfaceTypes.ICellConsumer, WebPart.UnlimitedConnections, ConnectionRunAt.ServerAndClient, Me, "CellConsumerInterface_WPQ_", "Get String Value", "Just a simple ICellConsumer") 'Description - MenuLabel - InterfaceClientReference - InterfaceObject - RunAtOptions - MaxConnections - InterfaceType - InterfaceName
        End Sub

        'Step #4: CanRunAt - called by framework to determine where a part can run.
        Public Overrides Function CanRunAt() As ConnectionRunAt
            'This Web Part can run on both the client and the server
            Return ConnectionRunAt.ServerAndClient
        End Function

        'Step #5: PartCommunicationConnect - Notification to the Web Part that it has been connected.
        Public Overrides Sub PartCommunicationConnect(ByVal interfaceName As String, ByVal connectedPart As WebPart, ByVal connectedInterfaceName As String, ByVal runAt As ConnectionRunAt)
            'Check to see if this is a client-side part
            If runAt Is ConnectionRunAt.Client Then
                'This is a client-side part
                _runAtClient = True
                Return
            End If

            '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_" Then
                'Keep a count of the connections
                _cellConnectedCount += 1
            End If
        End Sub

        'Step #6: PartCommunicationInit - Notification to the Web Part that it has been connected.
        Public Overrides Sub PartCommunicationInit()
            'If the connection wasn't actually formed then don't want to send Init event
            If _cellConnectedCount > 0 Then
                'If there is a listener, send init event
                If CellConsumerInitEvent IsNot Nothing Then
                    'Need to create the args for the CellConsumerInit event
                    Dim cellConsumerInitArgs As 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.
                    RaiseEvent CellConsumerInit(Me, cellConsumerInitArgs)
                End If
            End If
        End Sub

        '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 Overrides Function GetInitEventArgs(ByVal interfaceName As String) As InitEventArgs
            'Check if this is my particular cell interface
            If interfaceName = "MyCellConsumerInterface_WPQ_" Then
                EnsureChildControls()

                'Need to create the args for the CellConsumerInit event
                Dim cellConsumerInitArgs As New CellConsumerInitEventArgs()

                'Set the FieldName
                cellConsumerInitArgs.FieldName = _cellName
                cellConsumerInitArgs.FieldDisplayName = _cellDisplayName

                'return the InitArgs
                Return (cellConsumerInitArgs)
            Else
                Return (Nothing)
            End If
        End Function



        'Step #9.1: Implement CellProviderInit Event Handler.
        Public Sub CellProviderInit(ByVal sender As Object, ByVal cellProviderInitArgs As CellProviderInitEventArgs)
            '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.
        End Sub

        'Step #9.2: Implement CellReady Event Handler. 
        'Set label text based on value from the CellProvider Web Part
        Public Sub CellReady(ByVal sender As Object, ByVal cellReadyArgs As CellReadyEventArgs)
            'Set the label text to the value of the "Cell" that was passed by the Provider
            If cellReadyArgs.Cell IsNot Nothing Then
                _cellLabel.Text = cellReadyArgs.Cell.ToString()
            End If
        End Sub

        'Step #10: RenderWebPart - defines Web Part UI and behavior
        Protected Overrides Sub RenderWebPart(ByVal output As HtmlTextWriter)
            'Need to ensure that all of the Web Part's controls are created
            EnsureChildControls()

            'Render client connection code if needed
            If _runAtClient Then
                'Connected client-side
                Dim strClientCode As String = "<br><h5>Connected Client-Side</h5><br>" & vbLf
                strClientCode &= "<div id=""ConsumerDiv_WPQ_""/>" & vbLf
                strClientCode &= "<SCRIPT LANGUAGE=""JavaScript"">" & vbLf
                strClientCode &= "<!-- " & vbLf
                strClientCode &= "    var CellConsumerInterface_WPQ_ = new myCellConsumerInterface_WPQ_();" & vbLf

                strClientCode &= "    function myCellConsumerInterface_WPQ_()" & vbLf
                strClientCode &= "    {" & vbLf
                strClientCode &= "        this.PartCommunicationInit = myInit;" & vbLf
                strClientCode &= "        this.CellProviderInit = myCellProviderInit;" & vbLf
                strClientCode &= "        this.CellReady = myCellReady;" & vbLf

                strClientCode &= "        function myInit()" & vbLf
                strClientCode &= "        {" & vbLf
                strClientCode &= "            var cellConsumerInitArgs = new Object();" & vbLf
                strClientCode &= "            cellConsumerInitArgs.FieldName = ""CellName"";" & vbLf

                strClientCode &= "            WPSC.RaiseConnectionEvent(""MyCellConsumerInterface_WPQ_"", ""CellConsumerInit"", cellConsumerInitArgs);" & vbLf
                strClientCode &= "        }" & vbLf

                strClientCode &= "        function myCellProviderInit(sender, cellProviderInitArgs)" & vbLf
                strClientCode &= "        {" & vbLf
                strClientCode &= "        }" & vbLf

                strClientCode &= "        function myCellReady(sender, cellReadyArgs)" & vbLf
                strClientCode &= "        {" & vbLf
                strClientCode &= "            document.all('ConsumerDiv_WPQ_').innerHTML = cellReadyArgs.Cell;" & vbLf
                strClientCode &= "        }" & vbLf

                strClientCode &= "    }" & vbLf
                strClientCode &= "//-->" & vbLf
                strClientCode &= "</SCRIPT>"

                output.Write(ReplaceTokens(strClientCode))
            Else 'Connected server-side
                'If we are connected then display all child controls
                If _cellConnectedCount > 0 Then
                    '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")
                End If
            End If
        End Sub

        'Step #11.1 (Supporting Methods): CreateChildControls
        Protected Overrides Sub 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"
        End Sub
    End Class
End Namespace

Vea también

Otros recursos

Información general sobre conexiones a elementos web de ASP.NET