Procédure pas à pas : création de composants WebPart connectables dans SharePoint Foundation
Dernière modification : jeudi 29 septembre 2011
S’applique à : SharePoint Foundation 2010
Dans cet article
À propos des composants WebPart connectables
Création d'un composant WebPart qui implémente l'interface ICellProvider
Étape 1 : créer la classe d'interface
Étape 2 : déclarer les événements
Étape 3 : substituer la méthode EnsureInterfaces, puis appeler la méthode RegisterInterface
Étape 4 : substituer la méthode CanRunAt
Étape 5 : substituer la méthode PartCommunicationConnect
Étape 6 : substituer la méthode PartCommunicationInit
Étape 7 : substituer la méthode PartCommunicationMain
Étape 8 : substituer la méthode GetInitEventArgs
Étape 9 : implémenter les gestionnaires d'événements d'interface
Étape 10 : substituer la méthode RenderWebPart
Étape 11 : implémenter des méthodes de prise en charge
Une paire de composants WebPart qui implémentent les interfaces ICellProvider et ICellConsumer
Cette tâche de programmation explique comment faire pour créer deux composants WebPart SharePoint connectables : un composant WebPart qui peut consommer une valeur de cellule unique et un autre qui peut fournir une valeur de cellule unique.
Important
L’infrastructure WebPart dans Microsoft SharePoint Foundation repose sur l’infrastructure WebPart Microsoft ASP.NET et les composants WebPart qui dérivent de la classe WebPartASP.NET sont totalement pris en charge dans SharePoint, y compris le modèle de connexion ASP.NET. Dans la mesure du possible, vous devez créer des composants WebPart ASP.NET et utiliser le modèle de connexion ASP.NET pour connecter vos composants WebPart.
Pour plus d’informations sur le choix de la meilleure classe de base WebPart de dérivation, voir Développement de composants WebPart dans Windows SharePoint Services. Pour plus d’informations sur les composants WebPart ASP.NET et leur modèle de connexion, voir Vue d’ensemble des connexions WebPart dans la documentation ASP.NET.
À propos des composants WebPart connectables
L’infrastructure WebPart SharePoint fournit un ensemble standard d’interfaces appelées interfaces de connexion qui permettent aux composants WebPart d’échanger des informations entre eux lors de l’exécution. Par exemple, le composant WebPart Liste qui est intégré à SharePoint Foundation peut fournir (envoyer) une ligne de données à n’importe quel autre composant WebPart qui peut consommer (recevoir) cette ligne, tel qu’un composant WebPart qui implémente un formulaire pour afficher la ligne.
Étant donné que l’infrastructure WebPart fournit un ensemble standard d’interfaces de connexion, les composants WebPart connectables peuvent être développés par des sociétés ou développeurs totalement différents pour communiquer les uns avec les autres. Un composant qui prend en charge les interfaces de connexion peut être connecté par un utilisateur final avec Microsoft SharePoint Designer ou un navigateur Web. Cela permet aux utilisateurs finals de générer des combinaisons sophistiquées de composants WebPart via une interface utilisateur simple pilotée par des menus.
Les classes et les interfaces de connexion SharePoint Foundation sont implémentées dans l’espace de noms Microsoft.SharePoint.WebPartPages.Communication.
Interfaces de connexion
Les interfaces de connexion sont associées à des événements relatifs à un élément spécifique, tel qu'une ligne dans une liste. Les interfaces couplées forment un bus de communication entre les composants WebPart qui les implémentent. Un composant WebPart connectable déclenche un événement d'interface dans une ou plusieurs parties connectées pour qu'elles effectuent une action. Les interfaces sont associées en tant que fournisseur à un consommateur. Les événements du fournisseur sont gérés dans le consommateur et vice versa. Le tableau suivant décrit brièvement chaque paire d'interfaces de connexion.
Paire d'interfaces de connexion |
Description |
---|---|
Interfaces de connexion pour fournir ou consommer un élément à valeur unique, tel qu'une cellule ou un champ. |
|
Interfaces de connexion pour fournir ou consommer une seule ligne (ou plusieurs lignes) de valeurs. |
|
Interfaces de connexion pour fournir ou consommer une liste entière. |
|
Interfaces de connexion pour fournir ou consommer une valeur de filtre. Par exemple, le composant WebPart Liste prend en charge IListProvider, IRowProvider et IFilterConsumer. Étant donné que IRowProvider peut se connecter à IFilterConsumer, deux listes SharePoint distinctes peuvent être connectées à une autre liste. Cela permet à une liste de filtrer l'autre liste connectée. |
|
Les interfaces IParameterIn permettent la transmission et la réception de n'importe quel jeu de paramètres arbitraires entre composants WebPart. Ces interfaces couvrent une situation où le consommateur de composants WebPart possède la liste de paramètres et doit la communiquer à d'autres composants WebPart. |
|
Les interfaces IParameterOut permettent la transmission et la réception de n'importe quel jeu de paramètres arbitraires entre composants WebPart. Ces interfaces couvrent une situation où le fournisseur de composants WebPart possède la liste de paramètres et doit la communiquer à d'autres composants WebPart. |
Règles de compatibilité
Les composants WebPart peuvent uniquement être connectés s’ils sont compatibles. Voici plusieurs règles de compatibilité qui sont évaluées par l’infrastructure WebPart pour déterminer si deux composants WebPart peuvent être connectés. Si les composants WebPart ne sont pas compatibles, l’élément de menu Connexion dans le navigateur est désactivé et une info-bulle explique la raison de l’incompatibilité.
Paires opposées
Une interface de connexion peut uniquement se connecter aux autres interfaces compatibles. La règle de compatibilité la plus élémentaire est que les interfaces doivent être connectées en tant que paires opposées ou connectées via un transformateur. La connexion en tant que paires opposées signifie qu'un composant WebPart qui implémente l'interface IRowProvider peut se connecter à une autre partie qui implémente l'interface IRowConsumer.
Transformateurs
Dans le cas où un composant WebPart doit se connecter à une autre partie qui n'a pas exactement la même interface, l'infrastructure WebPart fournit les transformateurs d'interface, ce qui aide les utilisateurs à connecter deux interfaces distinctes d'une manière naturelle et transparente.
Par exemple, un utilisateur peut souhaiter connecter une liste de contacts à une visionneuse d'image. Toutefois, la liste de contacts a uniquement l'interface IRowProvider et la visionneuse d'images n'a que l'interface ICellConsumer. Pour résoudre ce problème, un transformateur d'interface permet à ces deux interfaces de se connecter entre elles.
Le tableau suivant montre les paires d’interfaces qui peuvent être connectées entre elles via un transformateur et indique si les connexions nécessitent Microsoft SharePoint Designer 2010.
Transformateur |
Connexion dans le navigateur |
Connexion dans SharePoint Designer 2010 |
---|---|---|
Oui |
Oui |
|
Oui |
Oui |
|
Non |
Oui |
|
Non |
Oui |
Connexions entre pages
Certaines interfaces sont autorisées à se connecter aux composants WebPart sur une page différente. Le comportement est semblable à un lien hypertexte.
Vous devez comprendre les points suivants relatifs aux connexions entre pages :
Un éditeur de pages Web compatible avec SharePoint Foundation, tel que SharePoint Designer 2010, est nécessaire pour créer des connexions entre pages. Toutefois, une fois qu’une connexion entre pages a été formée, elle peut être utilisée par n’importe quel navigateur Web pris en charge lors de l’exécution.
Seuls les composants WebPart connectables qui ont des implémentations conçues pour s'exécuter sur le serveur (la méthode CanRunAt a pour valeur ConnectionRunAtServer ou ServerAndClient) peuvent établir des connexions entre pages. Les connexions qui sont formées côté client ne sont pas autorisées à traverser des pages Web.
Le tableau suivant indique les interfaces qui peuvent être connectées sur plusieurs pages.
Interface de la page source |
Interface de la page cible |
---|---|
Lorsque vous utilisez des connexions de composants WebPart entre pages, vous devez effectuer les opérations suivantes :
Passer ConnectionRunAt.Server ou ConnectionRunAt.ServerAndClient au paramètre runAtOptions de la méthode RegisterInterface.
Passer true au paramètre allowCrossPageConnection de la méthode RegisterInterface.
Implémenter la méthode GetInitEventArgs pour fournir des informations spécifiques sur les données qui sont passées par le biais de l'interface de connexion.
Connexions client et serveur
À tout moment, les composants WebPart sont autorisés à s'exécuter sur le client ou le serveur. Certains des composants WebPart, s'ils sont conçus en conséquence, peuvent détecter les conditions sous lesquelles ils s'exécutent et basculer de manière dynamique entre une exécution sur le client ou le serveur. Les composants WebPart peuvent uniquement être connectés à d'autres composants WebPart s'exécutant dans le même emplacement. Par exemple, des parties côté serveur peuvent uniquement être connectées à d'autres parties côté serveur. Des parties côté serveur ne peuvent pas être connectées à des parties côté client. La chaîne de connexion doit être homogène. Si une partie peut de manière dynamique basculer entre les connexions client ou serveur, l'infrastructure WebPart ancre automatiquement le composant à une partie côté client ou côté serveur selon la chaîne WebPart à laquelle il est connecté.
Nombre maximal de connexions
Lorsque vous enregistrez une interface, le nombre maximal de connexions à d'autres composants WebPart peut être spécifié dans le paramètre maxConnections de la méthode RegisterInterface. Si la limite de connexion est dépassée sur un composant WebPart, celui-ci ne peut pas être connecté à d'autres parties.
Les options sont 1 ou illimité.
WebPart.UnlimitedConnections spécifie qu'un composant WebPart connectable peut accepter un nombre illimité de connexions à un autre composant.
WebPart.LimitOneConnection spécifie qu'un composant WebPart connectable peut accepter une seule connexion.
Pas de connexions circulaires
Un composant WebPart ne peut pas être connecté à lui-même, soit directement, soit par une chaîne de connexions.
Connexions des composants WebPart partagés et privés
Un composant WebPart partagé peut être connecté à un composant WebPart privé, si le composant WebPart privé est un consommateur et le composant WebPart partagé prend en charge un nombre illimité de connexions.
Flux de programme
Les composants WebPart connectés se passent des informations entre eux en déclenchant des événements d'interface spécifiques. Lorsqu'un composant WebPart implémente une interface comme ICellProvider, il doit substituer un certain nombre de méthodes. Le déclenchement des événements d'interface est effectué par l'appel de l'infrastructure du composant WebPart dans les méthodes substituées à des moments donnés. Les étapes suivantes de création de composants WebPart connectables définissent les méthodes qui doivent être substituées et le code par défaut qu'un auteur de composants WebPart doit utiliser à cet effet.
Création d'un composant WebPart qui implémente l'interface ICellProvider
Cette tâche de programmation définit le processus de création d'une classe qui implémente l'ensemble des méthodes et des événements nécessaires pour une interface de connexion à l'aide de l'interface ICellProvider. Pour un exemple de code complet, voir les exemples de code source ICellProvider et ICellConsumer à la fin de cette procédure.
Voici 11 étapes principales que vous devez effectuer pour implémenter une interface de connexion pour votre composant WebPart :
Créez la classe d'interface.
Déclarez les événements.
Substituez la méthode EnsureInterfaces, puis appelez la méthode RegisterInterface.
Substituez la méthode CanRunAt.
Substituez la méthode PartCommunicationConnect.
Substituez la méthode PartCommunicationInit.
Substituez la méthode PartCommunicationMain.
Substituez la méthode GetInitEventArgs .
Implémentez les gestionnaires d'événements de l'interface.
Substituez la méthode RenderWebPart.
Implémentez les méthodes de prise en charge.
Étape 1 : créer la classe d'interface
Créez une classe qui implémente l'une des interfaces de connexion prédéfinies. Dans cet exemple, nous allons implémenter l'interface ICellProvider. Pour les étapes restantes (2-11), l'ensemble du code va dans cette classe.
Exemple
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
Étape 2 : déclarer les événements
Déclarez tous les événements appropriés pour l'interface de connexion. Les autres variables utilisées par le composant WebPart sont également déclarées à cet emplacement. Étant donné que nous utilisons l'interface ICellProvider, l'exemple suivant déclare les variables de ses événements CellProviderInit et CellReady.
Exemple
// 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
Étape 3 : substituer la méthode EnsureInterfaces, puis appeler la méthode RegisterInterface
Substituez la méthode EnsureInterfaces. Cette méthode est appelée par l'infrastructure WebPart avant le rendu du composant WebPart et correspond au moment où le composant WebPart doit enregistrer toutes ses interfaces en appelant l'une des deux méthodes RegisterInterface.
Exemple
public override void EnsureInterfaces()
{
// Register Interfaces (See following section)
}
Public Overrides Sub EnsureInterfaces()
' Register Interfaces (See following section)
End Sub
Dans la méthode EnsureInterfaces substituée, vous indiquez à l’infrastructure WebPart les interfaces qui seront utilisées en appelant la méthode RegisterInterface. Tel qu’indiqué dans l’étape 3, la méthode RegisterInterface se produit dans la méthode EnsureInterfaces. La méthode RegisterInterface accepte plusieurs paramètres qui sont définis ci-après.
Définition de méthode
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
Notes
Une deuxième méthode RegisterInterface est disponible et fournit un paramètre allowCrossPageConnection supplémentaire pour spécifier explicitement si une interface prend en charge les connexions entre pages. La méthode RegisterInterface, qui n'inclut pas ce paramètre, code en dur le paramètre allowCrossPageConnection avec la valeur true pour toutes les interfaces de connexion qui sont prises en charge par les règles de compatibilité de connexion définies par l'infrastructure WebPart (voir « Connexions entre pages », précédemment dans cette rubrique). Toutes les autres interfaces de connexion sont codées en dur avec la valeur false.
Paramètres de méthode
Paramètre |
Description |
---|---|
interfaceName |
Propriété de chaîne qui est le nom convivial de l'interface. Le nom convivial doit être unique dans une partie. Cette propriété ne peut pas contenir les caractères spéciaux suivants : <, >, &, guillemet double, guillemet simple, virgule ou point-virgule. |
interfaceType |
Une propriété qui représente le type de l'interface (IRowProvider, ICellConsumer, etc.). |
maxConnections |
Une propriété que l’infrastructure WebPart peut interroger pour déterminer le nombre de connexions pouvant être formées sur une interface donnée. maxConnections est un int. Sa valeur peut être WebPart.LimitOneConnection ou WebPart.UnlimitedConnections. |
runAtOptions |
Définit l'emplacement d'exécution de l'interface (Client, Server, ClientAndServer, None). |
interfaceObject |
Une référence à l'objet réel qui implémente cette interface. |
interfaceClientReference |
Pour les connexions côté client, interfaceClientReference est une chaîne utilisée comme identificateur pour l'objet côté client qui implémente cette interface. Cet identificateur doit contenir un _WPQ_ afin de garantir l'unicité du nom, et il peut contenir des caractères spéciaux tels que (). Une chaîne vide peut être utilisée si la partie ne prend pas en charge la communication côté client. L'infrastructure WebPart code les guillemets doubles en tant que guillemets simples.
Remarque
WPQ_ est un jeton qui est remplacé par un identificateur unique par l'infrastructure WebPart lorsqu'une partie est restituée.
|
menuLabel |
Une étiquette générale ou explication de l'interface. Elle apparaît dans l'interface utilisateur du menu de connexion. Il est recommandé de commencer l'étiquette de menu à l'aide un verbe tel que « Provide » ou « Consume » afin que l'utilisateur qui crée une connexion comprenne la direction du flux de données. |
description |
Une description détaillée de l'interface. |
Exemple
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
Notes
Pour intercepter les exceptions d'autorisation de sécurité d'accès au code, placez l'appel RegisterInterface dans un bloc try/catch. Pour obtenir un exemple, voir la rubrique consacrée à la méthode RegisterInterface.
Étape 4 : substituer la méthode CanRunAt
Tous les composants WebPart connectables doivent substituer la méthode CanRunAt. Cette méthode est appelée par l'infrastructure WebPart afin de déterminer si un composant WebPart peut être exécuté sur le serveur, le client ou les deux. Le composant doit déterminer où il peut s'exécuter en fonction de la configuration actuelle du client de l'utilisateur et des autres composants WebPart auxquels il est connecté. Les valeurs pouvant être retournées sont les valeurs d'énumération ConnectionRunAt suivantes : Client,Server,ClientAndServer et None. Par exemple, un composant WebPart peut avoir deux rendus différents : riche et de niveau inférieur. Le composant WebPart peut nécessiter un composant ActiveX installé pour son rendu enrichi. Dans ce cas, la méthode CanRunAt retournerait Client si le composant ActiveX est installé ou Server s'il n'est pas installé.
Exemple
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;
}
Étape 5 : substituer la méthode PartCommunicationConnect
Tous les composants WebPart connectables doivent substituer la méthode PartCommunicationConnect. Cette méthode est appelée par l'infrastructure WebPart pour avertir le composant WebPart qu'il a été connecté, et passer en même temps des informations pertinentes telles que la partie à laquelle il était connecté. Cela se produit dès que l'infrastructure WebPart lie des événements appropriés pour la connexion. Dans cette méthode, l'auteur du composant WebPart doit assurer le suivi de l'emplacement où l'interface peut être exécutée, créer les contrôles d'interface utilisateur nécessaires et vérifier que la connexion a été formée correctement. Cette méthode a plusieurs paramètres qui sont définis ci-dessous.
Définition de méthode
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
Paramètres de méthode
Paramètre |
Description |
---|---|
interfaceName |
Nom convivial de l'interface qui est connectée. |
connectedPart |
Référence à l'autre composant WebPart qui est connecté. Les paramètres connectedPart et connectedInterfaceName fournissent un moyen à la partie de connexion pour identifier le type de partie à laquelle elle est connectée. Cela permet au composant WebPart d'établir une interaction plus informée avec l'autre partie. Par exemple, si la partie de code source a une connaissance approfondie de la partie cible, elle peut exploiter la partie cible du modèle objet public. Toutefois, les deux arguments doivent être conçus dans le but que cela fonctionne correctement. Par exemple, une partie graphique et une partie tableau croisé dynamique peuvent être conçues pour partager la même disposition d'une source de données commune lorsqu'elles ont été connectées. |
connectedInterfaceName |
Nom convivial de l'interface sur l'autre composant WebPart par le biais de laquelle ils sont connectés. |
runAt |
Emplacement d'exécution possible de l'interface. Ce sera le client ou le serveur, et il sera déterminé par l'infrastructure WebPart en fonction de plusieurs facteurs. |
Exemple
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
Étape 6 : substituer la méthode PartCommunicationInit
Un composant WebPart connectable peut éventuellement substituer la méthode PartCommunicationInit. Cette méthode est appelée par l'infrastructure WebPart pour autoriser le composant à déclencher les événements d'initialisation. Le composant doit déclencher les événements se terminant par « Init » (par exemple, CellProviderInit).
Les paramètres d'initialisation sont utiles lorsqu'un composant doit diffuser des informations sur lui-même aux autres parties. Par exemple, lorsqu'une partie de liste se connecte à une partie du formulaire, la partie liste diffuse ses noms de champs. La partie formulaire peut rendre ensuite son interface utilisateur basée sur les noms de champs de la partie liste.
Exemple
Notes
Pour les composants WebPart côté client, cet événement et son gestionnaire d'événements doivent être implémentés sur le client.
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
Étape 7 : substituer la méthode PartCommunicationMain
Un composant WebPart connectable peut éventuellement substituer la méthode PartCommunicationMain. Elle est appelée par l'infrastructure WebPart pour autoriser le composant à déclencher un autre événement à partir de l'interface (par exemple, CellReady). Pendant l'exécution de la méthode PartCommunicationMain, la communication réelle de valeurs de données (par opposition au schéma) a lieu entre composants WebPart.
Exemple
Notes
Pour les composants WebPart côté client, cet événement et son gestionnaire d'événements doivent être implémentés sur le client.
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
Étape 8 : substituer la méthode GetInitEventArgs
Un composant WebPart connectable peut substituer la méthode GetInitEventArgs si nécessaire. La méthode GetInitEventArgs est uniquement nécessaire pour les interfaces qui utilisent des transformateurs. Par exemple, IRowProvider, ICellConsumer, IFilterConsumer, IParametersOutProvider et IParametersInConsumer prennent en charge les transformateurs. La méthode GetInitEventArgs est appelée par les outils de création de connexions pour toutes les données nécessaires pour créer l'interface utilisateur du transformateur. La méthode retourne l'objet InitEventArgs et prend le nom de l'interface.
Par exemple, lors de la connexion de deux composants WebPart qui prennent en charge les interfaces IRowProvider et ICellConsumer, l’utilisateur doit spécifier quel champ du composant WebPart IRowProvider doit mapper à la valeur d’entrée dans le composant WebPart ICellConsumer. Cette opération est réalisée par l’infrastructure WebPart appelant la méthode GetInitEventArgs sur chacune des interfaces. Le navigateur ou les outils de création de connexions, tels que SharePoint Designer, utilisent les paramètres Init passés pour générer l’interface utilisateur du transformateur, ce qui permet à l’utilisateur de sélectionner le mappage de champ.
Définition de méthode
public override InitEventArgs GetInitEventArgs(string interfaceName)
Public Overrides Function GetInitEventArgs(ByVal interfaceName As String) As InitEventArgs
End Function
Paramètres de méthode
Paramètre |
Description |
---|---|
interfaceName |
Propriété de chaîne qui est le nom convivial de l'interface. |
Exemple
Notes
Cette méthode peut être implémentée sur le serveur ou client.
Important
Un exemple de code pour un composant WebPart qui implémente l'interface ICellProvider a été utilisé comme exemple dans ces étapes. Cependant, l'interface ICellProvider ne doit pas substituer la méthode GetInitEventArgs, car elle ne peut pas utiliser un transformateur. Toutefois, à des fins de précision, voici un exemple de l'exemple de code CellConsumer.cs à la fin de cette tâche de programmation, qui substitue la méthode 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
Étape 9 : implémenter les gestionnaires d'événements d'interface
Implémentez les gestionnaires d'événements appropriés en fonction du type d'interface utilisé. Dans cet exemple, l'interface ICellProvider doit implémenter le gestionnaire d'événements CellConsumerInitEventHandler. Ce gestionnaire d'événements doit être implémenté, que les données passées par l'interface ICellConsumer soient utilisées ou non. La partie consommateur déclenche cet événement lorsque sa méthode PartCommunicationInit s'exécute.
Définition de méthode
public void CellConsumerInit(object sender, CellConsumerInitEventArgs cellConsumerInitEventArgs)
Paramètres de méthode
Paramètre |
Description |
---|---|
sender |
L'objet qui appelle cette méthode. |
cellConsumerInitEventArgs |
Paramètres passés par le consommateur WebPart pendant la phase PartCommunicationInit. |
Exemple
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
Étape 10 : substituer la méthode RenderWebPart
Tous les composants WebPart doivent substituer la méthode RenderWebPart. Les détails de cette opération sont spécifiques à chaque composant. L'infrastructure WebPart appelle cette méthode pour restituer le composant WebPart. Pour obtenir un exemple complet, consultez le code source CellProvider.cs situé à fin de cette rubrique de tâche de programmation. Pour des raisons de concision, celui-ci fournit un exemple de structure.
Exemple
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
Étape 11 : implémenter des méthodes de prise en charge
Toutes les méthodes de prise en charge doivent être définies à cet emplacement dans le code source ICellProvider. Une structure est présentée ci-dessous. Pour obtenir un exemple complet, consultez le code source CellProvider.cs situé à fin de cette rubrique de tâche de programmation.
Exemple
// 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
Une paire de composants WebPart qui implémentent les interfaces ICellProvider et ICellConsumer
Les deux exemples de code suivants montrent comment créer deux composants WebPart connectables qui implémentent les interfaces ICellProvider et ICellConsumer.
Pour effectuer cette tâche de programmation, coupez et collez les exemples de code suivants dans deux fichiers C# de votre projet de composant WebPart, puis générez votre projet.
//--------------------------------------------------------------------
// 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