Search code examples
c#asp.netsharepointwindows-sharepoint-serviceswss-3.0

SharePoint / WSS3.0 : Creating static webpart connections at runtime


I've created several master / detail webparts that need to be connected. We have a requirement the the webparts self discover and connect to other connectable webparts on the page. I've acheived this in a standard ASP.NET page with the following code:

protected override void OnLoad(EventArgs e)
{    
    WebPartManager manager = WebPartManager.GetCurrentWebPartManager(Page);
    manager.StaticConnections.Add(new WebPartConnection()
    {
        ID = string.Format("WebPartConnection{0}{1}", this.ID, provider.ID),
        ConsumerID = this.ID,
        ConsumerConnectionPointID = "WebPartConnectableConsumer",
        ProviderID = provider.ID,
        ProviderConnectionPointID = "WebPartConnectableProvider"
    });
}

This approach, however, does not work in SharePoint. Using the SharePoint version of these objects results in a generic sharepoint error:

protected override void OnLoad(EventArgs e)
{    
    SPWebPartManager spManager = SPWebPartManager.GetCurrentWebPartManager(Page) as SPWebPartManager;
    spManager.StaticConnections.Add(new WebPartConnection()
    {
        ID = string.Format("WebPartConnection{0}{1}", this.ID, provider.ID),
        ConsumerID = this.ID,
        ConsumerConnectionPointID = "WebPartConnectableConsumer",
        ProviderID = provider.ID,
        ProviderConnectionPointID = "WebPartConnectableProvider"
    });
}

The following approach works, but creates the connection as part of the user's personalization:

protected override void OnLoad(EventArgs e)
{
    SPWebPartConnection connection = (from SPWebPartConnection c in spManager.SPWebPartConnections where c != null && c.Consumer == this && c.ConsumerConnectionPointID == "WebPartConnectableConsumer" && c.Provider == provider select c).FirstOrDefault();
    if (connection == null)
    {
        try
        {
            ProviderConnectionPointCollection providerCollections = spManager.GetProviderConnectionPoints(provider);
            ConsumerConnectionPointCollection consumerConnections = spManager.GetConsumerConnectionPoints(this);
            connection = spManager.SPConnectWebParts(provider, providerCollections["WebPartConnectableProvider"], this, consumerConnections["WebPartConnectableConsumer"]);
        }
        catch { }
    }
}

Solution

  • Hidden in the logs was an error stating that the StaticConnections property cannot be used in SharePoint/WSS environments. Instead, the SPWebPartConnections property must be used. Moreover, connections must be added prior to the load event (eg. OnInit).

    Working code:

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        SetUpProviderConnection();
    }
    
    private bool SetUpProviderConnection()
    {
        bool connectionCreated = false;
    
        WebPartManager manager = WebPartManager.GetCurrentWebPartManager(Page);
        foreach (System.Web.UI.WebControls.WebParts.WebPart webPart in manager.WebParts)
        {
            BaseWebPart provider = webPart as BaseWebPart;
            if (provider != null && (provider != this))
            {
                if (manager is Microsoft.SharePoint.WebPartPages.SPWebPartManager)
                {
                    SPWebPartManager spManager = SPWebPartManager.GetCurrentWebPartManager(Page) as SPWebPartManager;
    
                    spManager.SPWebPartConnections.Add(new SPWebPartConnection()
                    {
                        ID = string.Format("WebPartConnection{0}{1}", this.ID, provider.ID),
                        ConsumerID = this.ID,
                        ConsumerConnectionPointID = "WebPartConnectableConsumer",
                        ProviderID = provider.ID,
                        ProviderConnectionPointID = "WebPartConnectableProvider"
                    });
                }
                else
                {
                    manager.StaticConnections.Add(new WebPartConnection()
                    {
                        ID = string.Format("WebPartConnection{0}{1}", this.ID, provider.ID),
                        ConsumerID = this.ID,
                        ConsumerConnectionPointID = "WebPartConnectableConsumer",
                        ProviderID = provider.ID,
                        ProviderConnectionPointID = "WebPartConnectableProvider"
                    });
                }
                connectionCreated = true;
            }
        }
        return connectionCreated;
    }