//--------------------------------------------------------------------
// 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
}
}
}