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:
If you interrogate this page in SharePoint Manager, we can see:
Notice the collection and pre-rendered HTML for the links? Clicking on the ellipsis for the ManagedLinks property shows us:
Ah, the URLs! Excellent. So how does this work? Time to break out Reflector:
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”.
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:
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!
Thanks!
Hi, I need to show the custom listview count in summary link webpart. is it possible? can u explain pls..