Storing Data within Web Parts

We have a customer who wants a custom web part similar to the Summary Links web part – that is, editors can add links in this web part (along with some other metadata). For various reasons, a ListView web part and a Links library weren’t what they were after.

Now, the Summary Links web part seems to me to be a bit unusual. Most web parts access and use data stored elsewhere – lists, web services, databases, etc.. However, the Summary Links web part stores it’s data internally. How does it do that, and can I do the same?

To see this, I created a page with a Summary Links Web Part:

summary-links-web-part

If you interrogate this page in SharePoint Manager, we can see:

summary-links-web-part-in-sharepoint-manager

Notice the collection and pre-rendered HTML for the links? Clicking on the ellipsis for the ManagedLinks property shows us:

managed-links-collection-showing-link-urls

Ah, the URLs! Excellent. So how does this work? Time to break out Reflector:
reflector-view-of-web-part-code

There is actually quite a lot of code in the Summary Links web part, but this seemed to be the crux of it. It shows a hidden web part property at Shared scope. The ManagedLinks property provides access to the managedLinks private variable (note the capitalization – sucky coding practice, btw). That private variable is an ArrayList.

“Fair enough”, I thought, “I’ll do the same”:

private ArrayList _myLinks;
[WebBrowsable(false), Personalizable(PersonalizationScope.Shared)]
public ArrayList MyLinks
{
get
{
if (this._myLinks == null)
{
this._myLinks = new ArrayList();
}
return this._myLinks;
}
set
{
this._myLinks = value;
}
}

I ditched some of the attributes shown in Reflector on the basis that I didn’t have clue what they were doing!

Then I wrote my CreateChildControls function:
protected override void CreateChildControls()
{
base.CreateChildControls();
this.MyLinks.Add(DateTime.Now.ToLongTimeString());
Controls.Add(new LiteralControl("<ol>"));
foreach (object obj in MyLinks)
{
string linkval = (string)obj;
Controls.Add(new LiteralControl("<li>"+linkval ));
}
Controls.Add(new LiteralControl("</ol>"));
}

This should:

  • Add a string (The current time) to my ArrayList
  • Render an ordered list of all the time string stored in the ArrayList

I deployed my Web Part, added it to my web page, and refreshed it a few time to test it. It only ever showed the lastest time – not all the previous records. My data wasn’t being persisted. A bit of Googling later turned up the problem – you need to mark the data as dirty. I added this line after adding to my ArrayList:

this.SetPersonalizationDirty();

Great. Finally I published my page with my web part – and got the error “The file is not checked out. You must first check out this document before making changes”.

error

WTF? It took me a moment to realise – we were trying to update the web part (by calling SetPersonalizationDirty() ), and therefore update the page, but it wasn’t checked out! The error is quite right! I also now understood another reason why the Summary Links web part forces you to go to ‘Edit’ mode to add/edit links. It makes sense really.

So, the end result was a web part like this:

resulting-output-of-web-part

I’d added a bit of debug information about the ArrayList at the top. Naturally, it’s not a very useful web part, but it proves the technique and concept – storing objects in the ArrayList – and replicates how the Summary Links Web Part works. Now I just have to repeat this but to do something a bit more useful!

Advertisement
Storing Data within Web Parts

2 thoughts on “Storing Data within Web Parts

  1. Vels says:

    Hi, I need to show the custom listview count in summary link webpart. is it possible? can u explain pls..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.