Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

AjaxConnectedPageViewer

3.75/5 (4 votes)
17 Mar 2008CPOL 1   167  
With Microsoft ASP.NET AJAX 1.0, you can build more dynamic applications that come closer to the rich style of interruption-free interaction. This web part will give a full insight of site collections as a tree view and the respective attributes as a data grid, which are connected to each other.

Introduction

This is my second release as a development cycle of an AJAX Connectable webpart. While doing some R&D, I found that the RowConsumer and Provider interfaces, ICellConsumer and ICellProvider are more effective when we are writing a connectable web part in the AJAX framework.

Background

This is my second article, so for a more deep insight of AJAXConnectableWebPart, check out my previous article: AjaxConnectableWebPart_V1.0.0.0.

Using the code

First, we need to derive our web part from the ICellProvider interface:

C#
/// <summary>
/// This is an ajax-enabled webpart that sends
/// URL to a connectable PageViewer webpart
/// </summary>
public class AjaxUrlListWP : WebPart, ICellProvider
{
}

There are some events required by ICellProvider:

C#
//Events required by ICellProvider
public event CellProviderInitEventHandler CellProviderInit;
public event CellReadyEventHandler CellReady;
/// <summary>
/// This method is called by the Web Part infrastructure to notify the Web Part 
/// that it has been connected.
/// </summary>
/// <param name="interfaceName">Friendly name of the interface
///              that is being connected.</param>
/// <param name="connectedPart">Reference to the other Web Part
///              that is being connected to</param>
/// <param name="connectedInterfaceName">Friendly name of the interface
/// on the other Web Part through which they are connected</param>
/// <param name="runAt">Where the interface can be executed</param>
public override void PartCommunicationConnect(string interfaceName,
    WebPart connectedPart, string connectedInterfaceName, ConnectionRunAt runAt)
{
    //Receive connection from "Cell_Provider_Interface_WPQ_" interface only.
    if (interfaceName == "Cell_Provider_Interface_WPQ_")
    {
        //the connection is accepted, and the web part is connected now
        isConnected = true;                
    }
}

/// <summary>
/// This method is called by the Web Part infrastructure to allow the Web Part
/// to fire any initialization events
/// </summary>
public override void PartCommunicationInit()
{
    //if the web part is connected and the CellProviderInit listener is created,
    //create the args for CellProviderInit event and fire it to tell the Consumer
    //Web Part what type of cell it will be receiving when CellReady is fired later.
    if (isConnected && CellProviderInit != null)
    {
        CellProviderInitEventArgs cellProviderInitArgs = new CellProviderInitEventArgs();
        //set the field name.
        cellProviderInitArgs.FieldName = "URL";
        CellProviderInit(this, cellProviderInitArgs);
    }
}

/// <summary>
/// This is called by the Web Part infrastructure to allow the Web Part to fire any
/// of the other events from the interface (for example, CellReady). During the
/// execution of the PartCommunicationMain method, the actual communication of data
/// values takes place between Web Parts. 
/// </summary>
public override void PartCommunicationMain()
{
    //if the web part is connected and CellReady event is created,
    //create the args for this event and fire it.
    if (isConnected && CellReady != null)
    {
        CellReadyEventArgs cellReadyArgs = new CellReadyEventArgs();
        if (send_data && !string.IsNullOrEmpty(tv.SelectedValue))
        {
            //set the cell field with the selected URL
            //this field will be sent to the consumer.
            cellReadyArgs.Cell = tv.SelectedValue;
        }
        else
        {
            //nothing was selected
            cellReadyArgs.Cell = "";
        }
        CellReady(this, cellReadyArgs);
    }
}

/// <summary>
/// Register a client startup script to fixup the update panel, we need this
/// because Windows SharePoint Services JavaScript has a "form onSubmit wrapper"
/// which is used to override the default form action.
/// </summary>
private void EnsureUpdatePanelFixups()
{
    if (this.Page.Form != null)
    {
        //modify the form onSubmit wrapper
        if (this.Page.Form.Attributes["onsubmit"] == "return _spFormOnSubmitWrapper();")
        {
            this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
        }
    }
    //register the script
    ScriptManager.RegisterStartupScript(this, typeof(AjaxUrlListWP), "UpdatePanelFixup", 
      "_spOriginalFormAction = document.forms[0].action;" + 
      " _spSuppressFormOnSubmitWrapper=true;", true);
}

We are fetching the sub-sites at runtime, when the user expands the tree node. So, I have written a recursive method which will take care of filling the treeview at runtime.

C#
public void CreateTreeOnExpandNode(string URL, TreeNode nodeExpanded)
{
    try
    {
        SPSite site = new SPSite(URL);
        SPWeb web = null;
        if (site.Url == URL)
        {
            web = site.OpenWeb();
        }
        else
        {
            URL = URL.Replace(site.Url, "");
            if (site.ServerRelativeUrl != "/") URL = site.ServerRelativeUrl + URL;
            web = site.OpenWeb(URL);
        }
        foreach (SPWeb web1 in web.Webs)
        {
            TreeNode childnode = new TreeNode(web1.Url);
            //GetChild(web1, childnode);
            if (web1.Webs.Count > 0)
            {
                TreeNode emptyNode = new TreeNode();
                childnode.ChildNodes.Add(emptyNode);
            }
            nodeExpanded.ChildNodes.Add(childnode);
        }
    }
    catch (Exception ex)
    {
        Page.Response.Write(ex.Message);
    }
}

Consumer part: For creating the consumer part, I have derived my control class from the ICellConsumer interface, and the rest of the things are pretty similar to the provider part.

For getting data from the provider part:

C#
/// <summary>
/// Implements CellReady Event Handler. Receives data from provider
/// </summary>
/// <param name="sender">provider web part</param>
/// <param name="cellReadyArgs">arguments sent by the provider</param>
public void CellReady(object sender, CellReadyEventArgs cellReadyArgs)
{
    if (cellReadyArgs.Cell != null)
    {
        //gets the URL from the provider and save it in ContentLink
        ContentLink = cellReadyArgs.Cell.ToString();
    }
}

#endregion

Happy SharePointing! Cheers!!!

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)