yes. However, it wasn't as straight forward as I would have hoped.
Adding the toolbar button
Adding the button to the toolbar is pretty straight forward, you just need a feature with a CustomAction, which in turn adds the button...
<CustomAction Title="Up Folder"
Location="ViewToolbar"
Id="TheKid.UpFolder"
Sequence="100"
RegistrationType="ContentType"
RegistrationId="0x01"
Description="Navigates up a folder in a ListView Webpart"
ControlAssembly="TheKid.CustomActions.Backup, Version=1.0.0.0, Culture=neutral, PublicKeyToken=919ab618f7ce98cf"
ControlClass="TheKid.CustomActions.Backup.Action" />
This is using a class which inherits from SPLinkButton and displays the button on the ListViewWebPart toolbar. This works no problem and we can then write some code to navigate the 'Up Folder' functionality.
NOTE: In the CustomAction above we are using RegistrationType='ContentType' and RegistrationId="0x01". This is going to register this button for every content type (essentially every list & document library), so if you want to restrict this functionality you can by changing these values.
Formatting the link
The ListViewWebPart uses post-backs to change the folder displayed, in particular it uses a javascript function called EnterFoler to perform the postback. This function takes one parameter which is the formatted URL for the folder to which you wish to navigate. The URL should be the current URL with three parameters, the RootFolder, the Folder Content Type ID and the View Guid.
So to format the link we need to know the parent folder URL, which you would have thought you could get in code no problem...apparently not. I could not find anything which would give me access to the current folder of the ListView in order to workout the parent folder. Unfortunately I had to resort to reflection to get this information, not something I generally like doing and I wouldn't recommend it...but when needs must!!
The ListViewWebPart contains a private variable called 'rootFolder' that contains the current folder the webpart is displaying, as this was exactly what I needed I used that...
private static object GetPrivateFieldValue(object obj, string fieldName)
{
FieldInfo fi = obj.GetType().GetField(fieldName,
System.Reflection.BindingFlags.Instance
System.Reflection.BindingFlags.NonPublic);
return fi.GetValue(obj);
}
This code can be used to obtain the value of the private variable contained within the ListViewWebPart. This I used to not only get the 'rootFolder', but also a variable called 'folderCtId' which holds the content type ID (it's always been blank for me??).
With these two bits of information I was able to build the URL so that when the button was clicked it would navigate the ListView up to the parent folder...
string sCurrentUrl = HttpContext.Current.Request.Url.ToString();
if (sCurrentUrl.Contains("?")) sCurrentUrl = sCurrentUrl.Substring(0, sCurrentUrl.IndexOf("?"));
string sCTID = (string)GetPrivateFieldValue(lv, "folderCtId");
string sStart = ((sNewRootFolder == "") ? "?" : SPHttpUtility.EcmaScriptStringLiteralEncode(sCurrentUrl
+ "?RootFolder=" + sNewRootFolder) + "&");
sStart = SPHttpUtility.EcmaScriptStringLiteralEncode(sCurrentUrl + "?RootFolder=" + sNewRootFolder) + "&";
string sNavigateUrl = sStart
+ "FolderCTID=" + SPHttpUtility.EcmaScriptStringLiteralEncode(sCTID)
+ "&View=" + SPHttpUtility.EcmaScriptStringLiteralEncode(lv.ViewGuid)
+ "&Key=" + lv.StorageKey.ToString();
return "javascript:EnterFolder('" + sNavigateUrl + "');return false";
Here you see the URL being constructed with the required QueryString parameters. You will also see that I have added a 'Key' parameter, this was to ensure the button would work on a page with multiple ListViewWebParts. This 'Up Folder' button will work even when there are multiple webparts for the same document library...