Technical Fun

Archive for January 2008

Suddenly my team mate got this strange need to prevent folder creation inside MOSS document libraries. So I said “Aah .. “, and contemplated.

The logic should be simple, intercept the creation process, detect if the item being added to the doclib is really a folder, and cancel the event.
But the reality, the ItemAdding event wouldn’t let me do the detection process.

So, a brutal method was then picked 🙂
I resorted to the ItemAdded thing, and unleashed this evil;

public override void ItemAdded(SPItemEventProperties properties) { if (properties.ListItem.ContentType.Name == "Folder") { properties.ErrorMessage = "You can't create folders"; properties.ListItem.Delete(); } }

It worked. so stupidly enough, this will wipe the folder that you just created after detecting that the item you just added was a folder.

My two cents guys, who knows this might bail you out of jail too! 🙂

This one’s a sequel to my last post about LINQ-ize a SPListCollection.
I got another not-so-important urge to get a maximum number from one of my custom list’s field.
Let’s just say the the field containing the number is “Document Number”, and I want to grab the current maximum value of that field to do various purposes.

Now, as I am a little bit obsessed with Linq, so let’s leave CAML behind and grab Linq instead.
Let’s begin by creating a wrapper around SPListItemCollection object to make it Linq-able (just like I did with the SPListCollection).

public class SPListItemCollectionAdapter : List<SPListItem>
{
private SPListItemCollection _listItemCollection;

public SPListItemCollectionAdapter(SPListItemCollection listItemCollection)
{
_listItemCollection = listItemCollection;

Refresh();
}

private void Refresh()
{
this.Clear();

foreach (SPListItem item in _listItemCollection)
{
this.Add(item);
}
}

}

then voila!, you can use Linq’s aggregation function to grab the max value currently on a field called “Document Number” inside a list called “Document”. Write a method that might look like this:

private static double GetMaxFrom(string listname, string fieldname)
{
SPListItemCollection itemcol = mossWeb.Lists[listname].Items;
SPListItemCollectionAdapter itemsAdapter = new SPListItemCollectionAdapter(itemcol);
var result = itemsAdapter.Max(x => x[fieldname]);
return (double)result;
}

mossWeb is just a singleton for the SPWeb object, as I was using it numerous times on other methods as well.
I also took the liberty of using the lambda expression (x => x[fieldname]) just to evaluate the specific field.
Using it is as easy as calling GetMaxFrom("Document","Document Number");

After trying this LINQToSharePoint, I must admit I was a bit carried away in forcing Linq to my SharePoint programming needs.
I had this one very “not so important” ambition of iterating through SPList object within the SPListCollection on a SPWeb object.
Problem popped out, SPListCollection was not implementing IEnumerable, so I could not walk easily using Linq to this collection.
So.. to fulfill my ambition, I created a pseudo-adapter class which looked like this:

public class SPListCollectionAdapter : List<SPList>
{
private SPListCollection _listCol;

public SPListCollectionAdapter(SPListCollection listCol)
{
_listCol = listCol;

Refresh();
}

private void Refresh()
{
this.Clear();

foreach (SPList item in _listCol)
{
this.Add(item);
}
}
}

and shortly after that, I could then satisfy my quaint hunger with this method:

private static void DoMOSSLinq()
{
SPSite site = new SPSite(“http://titanctp2:9000&#8221;);
SPWeb web = site.AllWebs[0];

SPListCollectionAdapter listAdapter = new SPListCollectionAdapter(web.Lists);

var result = from l in listAdapter
select l;

foreach (var i in result)
Console.WriteLine(i.Title);

Console.ReadLine();
}

woohooo!!! I am no longer hungry.