<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Andy Burns' SharePoint Blog</title>
	
	<link>http://www.novolocus.com</link>
	<description>Whatever I'm working on, really...</description>
	<lastBuildDate>Mon, 05 Oct 2009 09:06:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/novolocus" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">novolocus</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Installing SharePoint on a K2 Server</title>
		<link>http://www.novolocus.com/2009/10/05/installing-sharepoint-on-a-k2-server/</link>
		<comments>http://www.novolocus.com/2009/10/05/installing-sharepoint-on-a-k2-server/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 09:06:39 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[K2]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1668</guid>
		<description><![CDATA[Okay, so I&#8217;ve not been blogging much recently as I have been sidetracked onto exciting deployment tests for the system we&#8217;ve been working on. However, I did come across this interesting issue&#8230;
Normally, if I were having K2 BlackPearl on the same box as SharePoint, I would install SharePoint first, then K2. This seems to work [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, so I&#8217;ve not been blogging much recently as I have been sidetracked onto exciting deployment tests for the system we&#8217;ve been working on. However, I did come across this interesting issue&#8230;</p>
<p>Normally, if I were having K2 BlackPearl on the same box as SharePoint, I would install SharePoint first, then K2. This seems to work without much fuss, and is the right way of doing it.</p>
<p>However, this time I had installed K2, and was now trying to install SharePoint (long story). However, SharePoint&#8217;s installer kept failing (using the SP2 with cumumlative updates to April, in a slipstream installer). It simply would not complete successfully.</p>
<p>Eventually, we tracked this down to the SQL 2005 Report Viewer. We uninstalled (via &#8216;Add an Remove Progams&#8217;) the &#8216;<em>Microsoft Report Viewer Redistributable 2005&#8242; </em>program, stopped the K2 BlackPearl service, and tried installing SharePoint again. It worked.</p>
<p>Of course, the idea would be, don&#8217;t have the two on the same box. But just in case someone else tries the same thing.</p>
<p>And I hope I&#8217;ll get back to development soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/10/05/installing-sharepoint-on-a-k2-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Conclusion</title>
		<link>http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/</link>
		<comments>http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 14:49:11 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1658</guid>
		<description><![CDATA[So, I thought a little wrap up of what we&#8217;ve seen and how I figured all this out. Much of what we&#8217;ve looked it is just a simplified version of the standard &#8216;People and Groups&#8217; pages, and a lot of digging around with reflector was involved!
We&#8217;ve seen:

That listing users is fairly simple using some &#8216;magic [...]]]></description>
			<content:encoded><![CDATA[<p>So, I thought a little wrap up of what we&#8217;ve seen and how I figured all this out. Much of what we&#8217;ve looked it is just a simplified version of the standard &#8216;People and Groups&#8217; pages, and a lot of digging around with reflector was involved!</p>
<p>We&#8217;ve seen:</p>
<ul>
<li>That listing users is fairly simple using some &#8216;magic values&#8217;, but that supporting the &#8216;View Selector&#8217; is a bit more complex!</li>
<li>That resolving the <em>MembershipGroupId</em> GET parameter is important, but pretty simple, and that there are many ways you could choose to do this.</li>
<li>That adding users is pretty simple too &#8211; it&#8217;s just the sort of SharePoint API code you&#8217;d get asked about in the WSS3 App Dev exam.</li>
<li>That removing users is a bit yucky &#8211; JavaScript to get the IDs of selected users &#8211; but again, the code itself is pretty straightforward.</li>
</ul>
<p>Now the moment you&#8217;ve been waiting for &#8211; <a href="http://www.novolocus.com/wp-content/uploads/2009/09/SimpleUG.zip">the code for the 3 pages we&#8217;ve used </a>itself. Note that I&#8217;ve also used a custom Master page for my sites &#8211; you&#8217;ll want to build your own, with your own navigation, etc..</p>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/">Introduction</a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/">How to Display a list of users</a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/">How to Find the MembershipGroupId</a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/">How to Add Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/">How to Remove Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/"><strong>Conclusion</strong></a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Removing Users</title>
		<link>http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/</link>
		<comments>http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 14:32:41 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>
		<category><![CDATA[Permissions]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1655</guid>
		<description><![CDATA[The final component in my users and groups UI is the ability to remove users. This is based very much on how SharePoint works &#8211; and it&#8217;s a little ugly. My apologies -but this is how SharePoint does it.
Our ListView shows our users. Each user has a checkbox next to them:

I&#8217;ve added a &#8216;Remove Users&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p>The final component in my users and groups UI is the ability to remove users. This is based very much on how SharePoint works &#8211; and it&#8217;s a little ugly. My apologies -but this is how SharePoint does it.</p>
<p>Our <strong>ListView</strong> shows our users. Each user has a checkbox next to them:</p>
<p><img title="ListView" src="http://www.novolocus.com/wp-content/uploads/2009/09/ListView-300x122.PNG" alt="ListView" width="300" height="122" /></p>
<p>I&#8217;ve added a &#8216;Remove Users&#8217; <strong>LinkButton</strong> to my fake &#8216;toolbar&#8217;:</p>
<p><img title="Title and View Controls" src="http://www.novolocus.com/wp-content/uploads/2009/09/Title-and-View-Controls-300x69.PNG" alt="Title and View Controls" width="300" height="69" /></p>
<p>That <strong>LinkButton</strong> is defined in my page as:</p>
<p><code>&lt;asp:LinkButton UseSubmitBehavior="false" id="BtnRemoveUsersFromGroup" runat="server"<br />
Text="Remove Users"<br />
OnClick="BtnRemoveUsersFromGroup_Click"<br />
OnClientClick="return BtnRemoveUsersClick();"<br />
/&gt;</code><br />
So, on click it runs some client script, and then posts back a click event. So, how do you know which users have been selected within the postback? You could have zero-to-N checkboxes!<span id="more-1655"></span></p>
<p>Well, the client script is some JavaScript that checks all the checkboxes, appends their values into a hidden field, and it&#8217;s that hidden field that is posted back for the click event.</p>
<p>This function gets the selected users (yes, I&#8217;m using a bit of jQuery &#8211; it was much neater):</p>
<p><code>function GetSelectedUsers(attributeName, separator)<br />
{<br />
var result = "";<br />
var users = $("input:checkbox[name^='spUserSelectionCheckBox']");<br />
for (var i = 0; i &lt; users.length; i++)<br />
{<br />
var chkBox = users[i];<br />
if (chkBox.checked)<br />
{<br />
var attributeValue = chkBox.getAttribute(attributeName);<br />
if (attributeValue != null &amp;&amp; attributeValue.length &gt; 0)<br />
{<br />
if (result.length &gt; 0)<br />
{<br />
result = result + separator;<br />
}<br />
result += attributeValue;<br />
}<br />
}<br />
}<br />
return result;<br />
}</code><br />
And this function puts all the selected users into our hidden field:</p>
<p><code>function BtnRemoveUsersClick()<br />
{<br />
var userIds = GetSelectedUsers("value", ",");<br />
var userNames = GetSelectedUsers("account", ",");<br />
var confirmMessage = "&lt;SharePoint:EncodedLiteral runat='server' text='&lt;%$Resources:wss,people_confirmremoveusersfromgroup%&gt;' EncodeMethod='EcmaScriptStringLiteralEncode'/&gt;";<br />
var noUserSelectedMsg = "&lt;SharePoint:EncodedLiteral runat='server' text='&lt;%$Resources:wss,people_nouserselected%&gt;' EncodeMethod='EcmaScriptStringLiteralEncode'/&gt;";<br />
if (userIds.length == 0)<br />
{<br />
alert(noUserSelectedMsg);<br />
return false;<br />
}<br />
var hdn = (document.getElementById("&lt;%= HdnUsersToRemove.ClientID %&gt;"));<br />
hdn.value = userIds;<br />
var msg = StBuildParam(confirmMessage, userNames);<br />
if(confirm(msg))<br />
{<br />
&lt;%= Page.GetPostBackEventReference(BtnRemoveUsersFromGroup) %&gt;;<br />
return true;<br />
}<br />
return false;<br />
}</code></p>
<p>For completeness, our hidden field is an ASP.NET control&#8230;</p>
<p><code>&lt;input runat="server" type="hidden" id="HdnUsersToRemove" /&gt;</code></p>
<p>Yuck! So, in JavaScript, we get all the checkboxes, identify the selected users, put them into a hidden field, and then postback our button&#8217;s click event. Thus, in my code behind, I have to split up my string of IDs of selected users, and remove the users:</p>
<p><code>web.AllowUnsafeUpdates = true;<br />
string[] usersToRemove = HdnUsersToRemove.Value.Split(new char[] { ',' });<br />
foreach (string user in usersToRemove)<br />
{<br />
group.Users.RemoveByID(int.Parse(user));<br />
}<br />
group.Update();<br />
web.AllowUnsafeUpdates = false;</code></p>
<p>And that&#8217;s the last main bit of it.</p>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/">Introduction</a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/">How to Display a list of users</a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/">How to Find the MembershipGroupId</a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/">How to Add Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/"><strong>How to Remove Users</strong></a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/">Conclusion</a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Adding Users</title>
		<link>http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/</link>
		<comments>http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 14:16:33 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>
		<category><![CDATA[People Picker]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1652</guid>
		<description><![CDATA[So, in the previous posts we&#8217;ve looked at how to resolve a MembershipGroupId for a group (or at least, one way of doing so), and how to list users. Now, how do we add new users to our group?
Well, on our &#8216;list of users&#8217; page, I have what looks like a a SharePoint toolbar. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>So, in the previous posts we&#8217;ve looked at how to resolve a MembershipGroupId for a group (or at least, one way of doing so), and how to list users. Now, how do we add new users to our group?</p>
<p>Well, on our &#8216;list of users&#8217; page, I have what looks like a a SharePoint toolbar. It&#8217;s actually just a table cunningly formatted to look like a toolbar, and the &#8216;Add users&#8217; link on it is a <strong>LinkButton</strong>. In the codebehind it&#8217;s click event is:</p>
<p><code>protected void BtnAddUsersToGroup_Click(object sender, EventArgs e)<br />
{<br />
int iGroup = (int)ViewState[GROUP];<br />
SPUtility.Redirect("SimpleUG/AddUsers.aspx?MembershipGroupId=" + iGroup, SPRedirectFlags.RelativeToLayoutsPage, this.Context);<br />
}</code></p>
<p>So, all we&#8217;re doing is going to a page called &#8216;AddUsers&#8217; and passing the <em>MembershipGroupId</em> again.<span id="more-1652"></span></p>
<p>This page looks like:</p>
<p><img title="custom-add-page" src="http://www.novolocus.com/wp-content/uploads/2009/05/custom-add-page-300x168.png" alt="custom-add-page" width="300" height="168" /></p>
<p>It&#8217;s much simpler than the normal add users page. We&#8217;re not giving the administrators as many options, which I think they&#8217;ll thank us for.</p>
<p>All we&#8217;ve got here is a PeoplePicker control. In the main content area of our page (having stripped out a lot of formatting) we&#8217;ve got:</p>
<p>     <code>&lt;wssawc:PeopleEditor<br />
AllowEmpty=false<br />
ValidatorEnabled="true"<br />
id="userPicker"<br />
runat="server"<br />
ShowCreateButtonInActiveDirectoryAccountCreationMode=true<br />
SelectionSet="User,SecGroup,SPGroup"<br />
/&gt;<br />
&lt;asp:Button UseSubmitBehavior="false" runat="server" OnClick="BtnOK_Click" Text="&lt;%$Resources:wss,multipages_okbutton_text%&gt;" id="btnOK" accesskey="&lt;%$Resources:wss,okbutton_accesskey%&gt;"/&gt;</code></p>
<p>So, a lot of formatting, a <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.peopleeditor.aspx"><strong>PeopleEditor</strong> </a>control, and a button to click OK. The main bit of the click event handler for the button is:</p>
<p><code>SPSecurity.RunWithElevatedPrivileges(delegate()<br />
{<br />
using (SPSite site = new SPSite(webUrl))<br />
{<br />
using (SPWeb web2 = site.OpenWeb())<br />
{<br />
web2.AllowUnsafeUpdates = true;<br />
for (int i = 0; i &lt; pickedList.Count; i++)<br />
{<br />
PickerEntity current = (PickerEntity)pickedList[i];<br />
SPUser user = web2.EnsureUser(current.Key);<br />
group.AddUser(user);<br />
}<br />
web2.AllowUnsafeUpdates = false;<br />
}<br />
}<br />
});</code></p>
<p>Here, for the group we&#8217;re adding to, we get each picked <strong>SPUser</strong> for the <strong>PeoplePicker</strong>, and add them to the group. Then I return the user to the list of users page.</p>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/">Introduction</a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/">How to Display a list of users</a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/">How to Find the MembershipGroupId</a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/"><strong>How to Add Users</strong></a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/">How to Remove Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/">Conclusion</a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Resolve the MembershipGroupID</title>
		<link>http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/</link>
		<comments>http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 14:03:40 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>
		<category><![CDATA[Permissions]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1644</guid>
		<description><![CDATA[So, one of the things I skipped over in my last post was just how you get the MembershipGroupID for the group you want the users to administer. Well, there are lots of options &#8211; all you&#8217;ve got to do is get to your page with the ListView with the correct value for the GET [...]]]></description>
			<content:encoded><![CDATA[<p>So, one of the things I skipped over in my last post was just how you get the MembershipGroupID for the group you want the users to administer. Well, there are lots of options &#8211; all you&#8217;ve got to do is get to your page with the ListView with the correct value for the GET parameter <em>MembershipGroupId</em>.</p>
<p>If you knew the ID in advance, you could hard code it. I didn&#8217;t, so I used a redirect page. <span id="more-1644"></span>My page accepts a GET parameter of &#8216;OWNERS&#8217;, &#8217;VISITORS&#8217;, or &#8216;MEMBERS&#8217; and redirects to the &#8216;list users&#8217; page with the correct group ID. Again, I wrote this page in visual studio as  code behind page to go in the _layouts directory.</p>
<p><code>protected void Page_Load(object sender, EventArgs e)<br />
{<br />
string group = Request.QueryString["group"];<br />
SPWeb web = SPContext.Current.Web;<br />
int igroup = web.AssociatedMemberGroup.ID;<br />
if (group != null)<br />
{<br />
if (group.ToUpper() == "OWNERS")<br />
{<br />
igroup = web.AssociatedOwnerGroup.ID;<br />
}<br />
else if (group.ToUpper() == "VISITORS")<br />
{<br />
igroup = web.AssociatedVisitorGroup.ID;<br />
}<br />
}<br />
SPUtility.Redirect("SimpleUG/ListUsers.aspx?MembershipGroupId=" + igroup, SPRedirectFlags.RelativeToLayoutsPage, this.Context);<br />
}</code><br />
That&#8217;s all there is too it &#8211; it get&#8217;s the &#8216;associated&#8217; group for the web. You could do whatever you want here, though &#8211; look up specific groups by name, permission level, as specified elsewhere, whatever. I then built into the navigation of my site links to things like:</p>
<p><code>/_layouts/SimpleUG/UserAdmin.aspx?Group=OWNERS</code></p>
<p>which would resolve the ID of the Owners group, and forward the user to a list of the users in that group.</p>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/">Introduction</a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/">How to Display a list of users</a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/"><strong>How to Find the MembershipGroupId</strong></a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/">How to Add Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/">How to Remove Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/">Conclusion</a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Listing Users</title>
		<link>http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/</link>
		<comments>http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 13:18:00 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1638</guid>
		<description><![CDATA[Listing users in my page was actually the easiest bit of the whole solution. In the ASP of my page, I added:
&#60;SharePoint:ListView id="UserListView" ListID="UserInfo" runat="server"/&#62;
And my page showed:

This is a SharePoint ListView, and the id and ListID appear to be &#8216;magic&#8217; values. If set as above, the web part will display the users in the [...]]]></description>
			<content:encoded><![CDATA[<p>Listing users in my page was actually the easiest bit of the whole solution. In the ASP of my page, I added:</p>
<p><code>&lt;SharePoint:ListView id="UserListView" ListID="UserInfo" runat="server"/&gt;</code></p>
<p>And my page showed:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/09/ListView.PNG"><img class="alignnone size-medium wp-image-1639" title="ListView" src="http://www.novolocus.com/wp-content/uploads/2009/09/ListView-300x122.PNG" alt="ListView" width="300" height="122" /></a></p>
<p>This is a SharePoint <strong>ListView</strong>, and the id and ListID appear to be &#8216;magic&#8217; values. If set as above, the web part will display the users in the group specified by the <em>MembershipGroupId</em> GET parameter for the page. Try it &#8211; go to the normal users and groups pages, to to view the members of a group, and try replacing the integer ID of the group. (Not all are used)</p>
<p>So, that bit of magic shows me the list of users. In my page&#8217;s <strong>OnLoad</strong> event I also read the <em>MembershipGroupId</em> parameter and used that to read the name of the group we&#8217;re editting, which I then used in the PageTitle area. We&#8217;ll see this later.</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/09/Title-and-View-Controls.PNG"><img class="alignnone size-medium wp-image-1640" title="Title and View Controls" src="http://www.novolocus.com/wp-content/uploads/2009/09/Title-and-View-Controls-300x69.PNG" alt="Title and View Controls" width="300" height="69" /></a></p>
<p><em>(My Site is called &#8216;Blank&#8217; and we&#8217;re editing the &#8216;Blank Members&#8217; group)</em></p>
<p>That&#8217;s all I needed really, but as a bonus I&#8217;m also going to describe how I added the View Control.<span id="more-1638"></span></p>
<p>The toolbar above my web part is actually an HTML table that I built by hand. The <em>Add Users</em> and <em>Remove Users</em> buttons are link buttons that I&#8217;ll describe in a later post. For now, let&#8217;s concentrate on the &#8216;View Selector&#8217; on the right.</p>
<p>To add this, I dug through the ordinary People and Groups pages and dug out the following code:</p>
<p><code>&lt;TD noWrap &gt;<br />
&lt;SharePoint:MenuTemplate runat="server" id="MenuTemplateView"/&gt;<br />
&lt;table border=0 cellpadding=0 cellspacing=0 style='margin-right: 4px'&gt;<br />
&lt;tr&gt;<br />
&lt;td nowrap id="topPagingCell"&gt;<br />
&lt;td&gt;<br />
&lt;td nowrap&gt;&amp;nbsp;&lt;/td&gt;<br />
&lt;td nowrap&gt;&lt;SharePoint:EncodedLiteral runat="server" text="&lt;%$Resources:wss,view_selector_view%&gt;" EncodeMethod='HtmlEncode'/&gt;&amp;nbsp;&lt;/td&gt;<br />
&lt;td nowrap onmouseover="this.className='ms-viewselectorhover'" onmouseout="this.className='ms-viewselector'" id="onetPeopleViewSelector"&gt;<br />
&lt;SharePoint:Menu id="MenuViewSelector" runat="server"<br />
TemplateId = "MenuTemplateView"<br />
Text="&lt;%$Resources:wss,multipages_new_menu_text%&gt;"<br />
MenuFormat="ArrowAlwaysVisible"<br />
MenuAlignment="Right"<br />
AlignmentElementOverrideClientId="onetPeopleViewSelector"<br />
HoverCellActiveCssClass = "ms-viewselectorhover"<br />
HoverCellInActiveCssClass = "ms-viewselector"<br />
ArrowImageUrl = "/_layouts/images/blank.gif"<br />
AccessKey = "&lt;%$Resources:wss,tb_ViewSelector_AK%&gt;" /&gt;<br />
&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/table&gt;<br />
&lt;/TD&gt;</code><br />
A lot of this code is actually HTML for the tables for format the control. The main two controls are the SharePoint <strong>Menu</strong> control and <strong>MenuTemplate</strong> controls. How they work here, I don&#8217;t know (a lot of this page was figured out using Reflector) &#8211; but it does give you a dropdown with the different views (<em>Details</em> and <em>List</em>) of the group in it.</p>
<p>If I was using different views, I needed to set my <strong>ListView</strong> to use the correct one. I did this in the Page&#8217;s <strong>OnLoad</strong> event, so my code became</p>
<p><code>protected override void OnLoad(EventArgs e)<br />
{<br />
base.OnLoad(e);<br />
UserListView.ViewId = this.CurrentViewId.ToString("B");<br />
this.UpdateViewSelector();<br />
string groupId = Request.QueryString["MembershipGroupId"];<br />
int iGroup = 0;<br />
if ((groupId != null) &amp;&amp; (int.TryParse(groupId, out iGroup)))<br />
{<br />
ViewState[GROUP] = iGroup;<br />
SPWeb web = SPContext.Current.Web;<br />
foreach (SPGroup group in web.AssociatedGroups)<br />
{<br />
if (group.ID == iGroup)<br />
{<br />
PageTitle.Text = group.Name;<br />
PageDisplayTitle.Text = group.Name;<br />
break;<br />
}<br />
}<br />
}<br />
else<br />
{<br />
ViewState[GROUP] = null;<br />
}<br />
}</code></p>
<p>Here you can see I set the <strong>ListView&#8217;s</strong> current view, based on the GUID for that view, and then get the group&#8217;s name for the page&#8217;s title. Now, in there there is a call to <em>UpdateViewSelector</em> &#8211; this reads as:</p>
<p><code>private void UpdateViewSelector()<br />
{<br />
this.MenuTemplateView.Controls.Clear();<br />
MenuItemTemplate template;<br />
foreach (SPView current in UserListView.List.Views)<br />
{<br />
if (!current.Hidden)<br />
{<br />
template = new MenuItemTemplate();<br />
template.Text = current.Title;<br />
template.ClientOnClickScript = "NavigateToView('"<br />
+ SPHttpUtility.EcmaScriptStringLiteralEncode(current.ID.ToString("B").ToUpperInvariant()) + "')";<br />
this.MenuTemplateView.Controls.Add(template);<br />
}<br />
}<br />
LiteralCurrentViewId.Text = CurrentViewId.ToString("B").ToUpperInvariant();<br />
SPView view2 = UserListView.List.Views[this.CurrentViewId];<br />
this.MenuViewSelector.Text = view2.Title;<br />
}</code><br />
This is setting up the View Selector&#8217;s <strong>MenuTemplate</strong>. It clears any existing menu items, and then adds one for each view in the <strong>ListView</strong>.</p>
<p>The final bit of code related to the View Selector is the page&#8217;s <em>CurrentViewId</em> property. This property returns the id of the view that&#8217;s currently being used, and it reads as:</p>
<p>  <code> private Guid _currentViewId = Guid.Empty;<br />
protected Guid CurrentViewId<br />
{<br />
get {<br />
if (_currentViewId == Guid.Empty)<br />
{<br />
string g = base.Request.QueryString["View"];<br />
Guid empty = Guid.Empty;<br />
if (g != null)<br />
{<br />
empty = new Guid(g);<br />
}<br />
SPView view = null;<br />
foreach(SPView current in UserListView.List.Views ) {<br />
if (!current.Hidden &amp;&amp; (((empty == Guid.Empty) &amp;&amp; current.DefaultView) || (empty == current.ID)))<br />
{<br />
view = current ;<br />
}<br />
}<br />
if (((view == null) &amp;&amp; (empty == Guid.Empty)) &amp;&amp; (UserListView.List.Views.Count &gt; 0))<br />
{<br />
view = UserListView.List.Views[0];<br />
}<br />
if (view == null)<br />
{<br />
throw new SPException(SPResource.GetString("ViewGone", new object[0]));<br />
}<br />
_currentViewId = view.ID;<br />
}<br />
return _currentViewId;<br />
}<br />
}</code></p>
<p>This returns the GUID of the view being currently used.</p>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/">Introduction</a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/"><strong>How to Display a list of users</strong></a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/">How to Find the MembershipGroupId</a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/">How to Add Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/">How to Remove Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/">Conclusion</a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I simplified the Users and Group UI – Intro</title>
		<link>http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/</link>
		<comments>http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 13:55:18 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[People and Groups]]></category>
		<category><![CDATA[Permissions]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1636</guid>
		<description><![CDATA[Previously, I&#8217;d blogged about a simplified Users and Groups UI for SharePoint. I really annoys me that the standard one is so complex &#8211; I&#8217;m a techy, and a specialist, and it confuses me! I&#8217;m not sure what chance non-specialist admins will have.
The worst part is, though, often users just want to add or remove [...]]]></description>
			<content:encoded><![CDATA[<p>Previously, I&#8217;d blogged about a simplified Users and Groups UI for SharePoint. I really annoys me that the standard one is so complex &#8211; I&#8217;m a techy, and a specialist, and it confuses me! I&#8217;m not sure what chance non-specialist admins will have.</p>
<p>The worst part is, though, often users just want to add or remove users from a pretty limited set of groups. I mean, this is implied by the standard &#8216;Visitors/Members/Owners&#8217; groups on a site. Unfortunately, there are often a <em>lot</em> of other groups, and other complexities shown through the standard user interface in SharePoint.</p>
<p>For a Case Management system we&#8217;ve been working on, I built a simplified user interface. The idea was to make it easy for non-techies to add and remove users from <em>specific</em> groups. They weren&#8217;t to have access to all groups, and this wasn&#8217;t to replace the ordinary People and Groups pages &#8211; so more technical staff could still use those too. What I came up with is shown below.</p>
<p><em><a href="http://www.novolocus.com/wp-content/uploads/2009/05/case-permissions-page.png"><img title="case-permissions-page" src="http://www.novolocus.com/wp-content/uploads/2009/05/case-permissions-page-300x164.png" alt="case-permissions-page" width="300" height="164" /></a></em></p>
<p>It appears similar, initially – but the navigation on the left is the same as for the rest of our case site. Only the relevant groups (“<em>Case Workers</em>” and “<em>Case Owners</em>”) are linked to on the left, and these links are only shown to users who can edit the groups (<em>Home </em>and <em>Audit </em>aren’t related to people and groups). Also, the menus on this page only let users add or remove users – which is all they should need to do.</p>
<p>Note that the &#8220;Case Workers&#8221; and &#8220;Case Owners&#8221; groups are just the groups we happened to be using &#8211; you could build this to work for others, depending on your needs.</p>
<p>I built this user interface using 3 application pages put into the _<em>layouts</em> directory. They&#8217;re actually Code Behind ASPX pages, and so this is a Visual Studio solution, though some sections of the application could be built in SharePoint Designer.</p>
<p>The pages themselves are for:</p>
<ul>
<li>Listing the users and letting admins remove users.</li>
<li>A page for adding new users.</li>
<li>A redirect page for identifying the correct ID for the group we want to edit.</li>
</ul>
<p>The solution is a little complicated, so I&#8217;m going to break it down into pieces:</p>
<ul>
<li><a href="http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/"><strong>Introduction</strong></a></li>
<li><a href="http://www.novolocus.com/2009/09/17/how-i-simplified-the-users-and-group-ui-listing-users/">How to Display a list of users</a></li>
<li><a href="http://www.novolocus.com/2009/09/18/how-i-simplified-the-users-and-group-ui-resolve-the-membershipgroupid/">How to Find the MembershipGroupId</a></li>
<li><a href="http://www.novolocus.com/2009/09/21/how-i-simplified-the-users-and-group-ui-adding-users/">How to Add Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/22/how-i-simplified-the-users-and-group-ui-removing-users/">How to Remove Users</a></li>
<li><a href="http://www.novolocus.com/2009/09/23/how-i-simplified-the-users-and-group-ui-conclusion/">Conclusion</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/16/how-i-simplified-the-users-and-group-ui-intro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event Properties AfterProperties – what should they be?</title>
		<link>http://www.novolocus.com/2009/09/02/event-properties-afterproperties-what-should-they-be/</link>
		<comments>http://www.novolocus.com/2009/09/02/event-properties-afterproperties-what-should-they-be/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:08:49 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SPField]]></category>
		<category><![CDATA[SPFieldCollection]]></category>
		<category><![CDATA[SPItemEventReceiver]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1628</guid>
		<description><![CDATA[While working on pre-filling ListItem fields on an item, I became a bit puzzled. The SPItemEventProperties.AfterProperties collection is a dictionary which can contain the named value for one of the fields of the item. In other words, if we wanted to set a value &#8220;Tax Area&#8221; to &#8220;Europe&#8221; we&#8217;d do:
properties.AfterProperties["Tax Area"] = "Europe";
In our case, [...]]]></description>
			<content:encoded><![CDATA[<p>While working on <a href="http://www.novolocus.com/2009/08/25/pre-filling-fields-on-editform-aspx/">pre-filling ListItem fields on an item</a>, I became a bit puzzled. The<strong> </strong><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventproperties.afterproperties.aspx"><strong>SPItemEventProperties.AfterProperties</strong> </a>collection is a dictionary which can contain the named value for one of the fields of the item. In other words, if we wanted to set a value &#8220;Tax Area&#8221; to &#8220;Europe&#8221; we&#8217;d do:</p>
<p><code>properties.AfterProperties["Tax Area"] = "Europe";</code></p>
<p>In our case, however, we didn&#8217;t know what these properties were before hand. Rather, we were &#8216;inheriting&#8217; values from a parent folder. Thus, we were going to use the parent folder&#8217;s SPField object for each field to define the value. I started out using:</p>
<p><code>properties.AfterProperties[parentField.Title] = parentItem[parentField.id];</code></p>
<p>But is <strong>Title</strong> the right property to use? Well, having looked through a number of blog posts, this seems to be the subject of some confusion.</p>
<p>At first <strong>Title</strong> is okay to use. However, you can change the display name of the field. For example, we could change our field&#8217;s <strong>Title</strong> to &#8216;Tax Region&#8217; &#8211; but we still need to use &#8216;Tax Area&#8217; in our <strong>AfterProperties</strong> collection.</p>
<p>So, <strong>InternalName</strong> is the right property of the <strong>SPField</strong> to use &#8211; but there is a hiccup. The <strong>InternalName</strong> is encoded &#8211; <code>Tax_x0020_Area</code> &#8211; so you have to <a href="http://www.novolocus.com/2009/09/02/escape-and-unescape-internal-names/">unescape it like I&#8217;ve talked about before</a>.</p>
<p>The summary is, then, use the unescaped <strong>InternalName</strong> in your <strong>AfterProperties</strong> collection.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/02/event-properties-afterproperties-what-should-they-be/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Escape and Unescape Internal Names</title>
		<link>http://www.novolocus.com/2009/09/02/escape-and-unescape-internal-names/</link>
		<comments>http://www.novolocus.com/2009/09/02/escape-and-unescape-internal-names/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 10:45:46 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1626</guid>
		<description><![CDATA[If you&#8217;re a SharePoint Dev you&#8217;re bound to come across the curious escaping used in some text. Text like:
Hello World
Gets encoded to:
Hello_x0020_World
So what&#8217;s the _x0020_ number about? Well, hex 20 is the UTF value for a space, and x0020 represents that space. I guess the underscores are delimiters. The reason for this escaping is that XML element [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a SharePoint Dev you&#8217;re bound to come across the curious escaping used in some text. Text like:</p>
<p><code>Hello World</code></p>
<p>Gets encoded to:</p>
<p><code>Hello_x0020_World</code></p>
<p>So what&#8217;s the <code>_x0020_</code> number about? Well, hex 20 is the UTF value for a space, and <code>x0020 </code>represents that space. I guess the underscores are delimiters. The reason for this escaping is that XML element names can&#8217;t have a space.</p>
<p>How would I encode or decode this? Well, the clue is in the phrase &#8216;XML element names&#8217;. You can use:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.encodename.aspx"><strong>System.XML.XmlConvert.EncodeName()</strong></a> to encode</li>
<li><a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.decodename.aspx"><strong>System.XML.XmlConvert.DecodeName()</strong></a> to decode</li>
</ul>
<p>Both are static.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/09/02/escape-and-unescape-internal-names/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Web Part Management Page</title>
		<link>http://www.novolocus.com/2009/08/28/web-part-management-page/</link>
		<comments>http://www.novolocus.com/2009/08/28/web-part-management-page/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 15:49:33 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1623</guid>
		<description><![CDATA[It&#8217;s well known, but mostly to remind myself &#8211; if you&#8217;ve got a web part that causes problem on a page (like the yellow screen of death) and you want to remove it, add the following to your url:
?contents=1
Takes you to the Web Part Maintenance Page. I can never remember the bit you add to [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s well known, but mostly to remind myself &#8211; if you&#8217;ve got a web part that causes problem on a page (like the yellow screen of death) and you want to remove it, add the following to your url:</p>
<p><code>?contents=1</code></p>
<p>Takes you to the Web Part Maintenance Page. I can never remember the bit you add to the URL</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/08/28/web-part-management-page/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pre-filling fields on EditForm.aspx</title>
		<link>http://www.novolocus.com/2009/08/25/pre-filling-fields-on-editform-aspx/</link>
		<comments>http://www.novolocus.com/2009/08/25/pre-filling-fields-on-editform-aspx/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 12:30:07 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ItemAdded]]></category>
		<category><![CDATA[ItemAdding]]></category>
		<category><![CDATA[SPItemEventReceiver]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1619</guid>
		<description><![CDATA[I&#8217;ve just been looking at an interesting problem that a colleague has had. We&#8217;ve a customer who wants to &#8216;inherit&#8217; metadata values from Folders in a SharePoint Document Library to Documents uploaded to within it. For example, if the Folder has  column &#8216;Case ID&#8217;, they want the value of the &#8216;Case ID&#8217; column of any [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just been looking at an interesting problem that a colleague has had. We&#8217;ve a customer who wants to &#8216;inherit&#8217; metadata values from Folders in a SharePoint Document Library to Documents uploaded to within it. For example, if the Folder has  column &#8216;Case ID&#8217;, they want the value of the &#8216;Case ID&#8217; column of any Document within it to be automatically set to the same value. And another twist &#8211; we won&#8217;t know the columns beforehand.</p>
<p>The problem is, they want this value to be pre-populated <em>before</em> the EditForm.aspx page is displayed.</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/08/AutoPopulated-Field.PNG"><img class="alignnone size-medium wp-image-1620" title="AutoPopulated Field" src="http://www.novolocus.com/wp-content/uploads/2009/08/AutoPopulated-Field-300x145.PNG" alt="AutoPopulated Field" width="300" height="145" /></a></p>
<p>Here, for example, the Case ID is autopopulated from the parent folder. So, what&#8217;s the best way of doing that?<span id="more-1619"></span></p>
<p>Well, clearly an <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventreceiver.aspx"><strong>SPItemEventReceiver</strong> </a>class seems a good bet. We can override one of the events, and in the event get the parent folder, and map across any column values. But what event should we override?</p>
<ul>
<li><strong>ItemAdding</strong> seems a good choice. This is a &#8221;<em>Synchronous <strong>Before</strong> event that occurs when a new item is added to its containing object</em>&#8220;. However, because this is <em>before</em> the item is added, there is no <strong>SPListItem</strong> object to write the values too, or to even see what fields the item has.</li>
<li>Consequently, my colleague had decided to use the <strong>ItemAdded</strong> event. This is an &#8220;<em>Asynchronous <strong>After</strong> event that occurs after a new item has been added to its containing object</em>.&#8221; Note that is is Asynchronous. That is, it runs in a different thread, at an indeterminate time.</li>
</ul>
<p>As has been <a href="http://hristopavlov.wordpress.com/2009/02/17/understanding-sharepoint-list-forms/">blogged</a> about elsewhere, this puts the <em>EditForm.aspx</em> page and our event handler into race conditions. The edit form contains a &#8216;last update&#8217; time, to detect concurrent updates. Our event handler update the item. The possible outcomes are:</p>
<ul>
<li>If the event receiver wins, all is good. The item gets it&#8217;s parents values, then the edit form displays with those values.</li>
<li>If the form wins, it displays without any inherited values. <em>Then</em> the event receiver updates the item, which means that when the users tries to save changes they&#8217;ve made in the edit form, they receive an error telling them &#8220;<em>The file X has been modifed by Y</em>&#8220;</li>
</ul>
<p>So, what&#8217;s the solution? Well, although the ItemAdding event doesn&#8217;t have an <strong>SPListItem</strong> to set the values for &#8211; &#8216;cos it&#8217;s not been created yet - the properties of the event does have an <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventproperties.afterproperties.aspx"><strong>AfterProperties</strong> </a>collection. This is a set of values we want set in the properties of our new item when it is finally created. Note that the collection is keyed on the <strong>DisplayName</strong>, not the <strong>InternalName</strong>, <a href="http://www.lifeonplanetgroove.com/blog/index.php/2008/06/06/workarounds-for-itemadding-itemadded-event-handlers/">at least on my system</a>.</p>
<p>Now, we don&#8217;t what the Fields we&#8217;re mapping are beforehand. And as our <strong>SPListItem</strong> doesn&#8217;t exist yet, we can&#8217;t look the up &#8211; so how do we handle that? Well, I copy all the parent Folder&#8217;s properties. Fields that are the same on the child will use the value of the appropriate property &#8211; and additional properties won&#8217;t be used. For example, if our Folder has a &#8216;Case Owner&#8217; and our Document does not, we&#8217;ll be setting a property called &#8216;Case Owner&#8217; on the child item &#8211; but it isn&#8217;t used, and so it isn&#8217;t a problem, and we can always find and remove it on <strong>ItemUpdated</strong>.</p>
<p><code>public override void ItemAdding(SPItemEventProperties properties) {<br />
//Get the URL to the folder we're working at.<br />
using(SPWeb web = properties.OpenWeb()){<br />
string url = properties.BeforeUrl.ToString();<br />
url = url.Substring(0,url.LastIndexOf("/"));<br />
//Get the folder we're using. Get the ListItem too (if it has one<br />
// - root folders don't<br />
SPFolder folder = web.GetFolder(url);<br />
SPListItem folderItem = folder.Item;<br />
//If not a root folder...<br />
if (folderItem != null) {<br />
//For each folder field, if it's inheritable, add it as a property.<br />
//This may add unnecessary properties - ones for which the child doesn't<br />
//have a field. See ItemUpdated.<br />
SPContentType folderContentType = folderItem.ContentType;<br />
foreach (SPField field in folderContentType.Fields) {<br />
if (IsInheritable(field)) {<br />
properties.AfterProperties[field.Title] = folderItem[field.Id].ToString();<br />
}<br />
}<br />
}<br />
} //End Using<br />
}</code></p>
<p><strong>EDIT &#8211; there is an error in this code &#8211; AfterProperties should be set <a href="http://www.novolocus.com/2009/09/02/event-properties-afterproperties-what-should-they-be/">as shown here</a>, not using field.Title</strong></p>
<p>Note that the IsInheritable function is &#8216;cos we do have some extra criteria over what fields to map (they have to be from a certain <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield.group.aspx">Group </a>of Site Columns)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/08/25/pre-filling-fields-on-editform-aspx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ASP Charting Settings for SharePoint</title>
		<link>http://www.novolocus.com/2009/08/18/asp-charting-settings-for-sharepoint/</link>
		<comments>http://www.novolocus.com/2009/08/18/asp-charting-settings-for-sharepoint/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 12:00:19 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[Polls]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1616</guid>
		<description><![CDATA[So, we&#8217;ve a customer who wanted a cheap and cheerful Polling web part. I&#8217;d seen one before on Codeplex by Phil Wicklund, and more recently I&#8217;d noticed the SPUserPoll by Edwin Vriethoff web part also on Codeplex. (I might try to review it at some point soon).

Both these web parts look kind of similar. They [...]]]></description>
			<content:encoded><![CDATA[<p>So, we&#8217;ve a customer who wanted a cheap and cheerful Polling web part. I&#8217;d <a href="http://www.novolocus.com/2009/03/30/polling-web-part-by-phil-wicklund/">seen one before </a>on <a href="http://pollingwebpart.codeplex.com/">Codeplex </a>by <a href="http://philwicklund.com/freeware/polling/default.aspx">Phil Wicklund</a>, and more recently I&#8217;d noticed the <a href="http://www.codeplex.com/SPUserPoll">SPUserPoll </a>by <a href="http://edwin.vriethoff.net/">Edwin Vriethoff </a>web part also on Codeplex. (I might try to review it at some point soon).</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/03/results.png"><img class="alignnone size-medium wp-image-1202" title="results" src="http://www.novolocus.com/wp-content/uploads/2009/03/results-208x300.png" alt="results" width="208" height="300" /></a></p>
<p>Both these web parts look kind of similar. They should do &#8211; they use the same control to display the charts &#8211; the ASP <strong>Chart</strong> control in <strong>System.Web.UI.DataVisualization.Charting</strong> library. <span id="more-1616"></span></p>
<p>MSDN doesn&#8217;t seem to have much info on this; it implies that it&#8217;s part of the .NET 4 beta, but it is definitely available in 3.5 &#8211; <a href="http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx">Scott Gu says so</a>, and observation shows he&#8217;s right!</p>
<p>We had a problem, though, on one of our system that sometimes the chart image would be displayed correctly &#8211; but most of the time you just got an &#8216;error&#8217; box where the image should be. If you kept refreshing the page, occasionally it would show the image, but mostly it showed the error box &#8211; but it seemed pretty random as to when it would work or not.</p>
<p>It struck me that I should understand the configuration I&#8217;d put into the Web.Config. While doing this, I noticed that the value for the &#8216;ChartImageHander&#8217; setting was</p>
<p><code>&lt;add key="ChartImageHandler" value="Storage=memory;Timeout=20;" /&gt;</code></p>
<p>I wondered what the storage options were. I mean, if there were multiple servers you&#8217;d be relying upon Sticky Sessions to get the right server that has your image stored. Well, I found<a href="http://blogs.msdn.com/deliant/archive/2008/12/02/managing-chart-generated-images-with-chart-image-handler.aspx"> this blog post </a>(and later, <a href="http://msdn.microsoft.com/en-us/library/dd456629(VS.100).aspx">this documentation</a>) that describes it. I noticed:</p>
<blockquote><p><strong>memory</strong>: Store the rendered chart images in the memory space of the running process. Do not use this option in a server cluster or a multiple-process site.</p></blockquote>
<p>That&#8217;s enough to make me suspicious. Instead, I created a directory to hold the chart files, and used</p>
<p><code>&lt;add key="ChartImageHandler" value="Storage=file;Timeout=20;Dir=c:\charttemp\" /&gt;</code></p>
<p>One additional note &#8211; I&#8217;m not sure if the ChartImageHandler should also include &#8216;DeleteAfterServicing=false&#8217; to act like a cache. Sure, the chart wouldn&#8217;t get updated right away each time &#8211; but neither would it have to be rendered so often. I might look into that at some point&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/08/18/asp-charting-settings-for-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSPBuilder and CAS Policies</title>
		<link>http://www.novolocus.com/2009/08/13/wspbuilder-and-cas-policies/</link>
		<comments>http://www.novolocus.com/2009/08/13/wspbuilder-and-cas-policies/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 10:28:13 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[WSPBuilder]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1607</guid>
		<description><![CDATA[Recently I wrote a web part using the WSPBuilder Visual Studio add-ins. I wanted to deploy it to the BIN directory and not have to elevate the trust level of my farm, so I was going to have to write a Code Access Security Policy (CAS Policy).
Others have written good descriptions of what CAS Policy is (here [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote a web part using the WSPBuilder Visual Studio add-ins. I wanted to deploy it to the BIN directory and not have to elevate the trust level of my farm, so I was going to have to write a Code Access Security Policy (CAS Policy).</p>
<p>Others have written good descriptions of what CAS Policy is (here is <a href="http://store.bamboosolutions.com/kb/article.aspx?id=10405">a good description by Bamboo</a>), but the short description is that it tells your application (SharePoint) to give certain additional rights to an assembly (in our case, the web part). These rights are things like being able to access the disc, the network, or even the SharePoint Object Model!</p>
<p>Yup, that&#8217;s right &#8211; under default Code Access Security, my assembly wouldn&#8217;t even be able to access the SharePoint APIs.<span id="more-1607"></span></p>
<p>Anyway, I started looking into I&#8217;d have to do to add a policy. Basically, it&#8217;s a lump of XML that goes in the Manifest file of your WSP. Conveniently, I discovered, WSPBuilder automatically performs reflection on my assembly, and generates a CAS Policy by itself:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/08/Automatic-CAS-Policy.PNG"><img class="alignnone size-medium wp-image-1608" title="Automatic CAS Policy" src="http://www.novolocus.com/wp-content/uploads/2009/08/Automatic-CAS-Policy-300x118.PNG" alt="Automatic CAS Policy" width="300" height="118" /></a></p>
<p>If you open that image up, what you&#8217;ll see is a set of permissions being defined, and then at the bottom the assemblies (just the one in my case) that those assemblies apply to.</p>
<p>I was surprised that my automatic CAS policy contained rights for things like File IO, SMTP and SQL Client &#8211; but my web part uses the SharePoint object model, and that probably uses all those rights.</p>
<p>So, an automatically generated CAS Policy &#8211; nice, neat! It didn&#8217;t work. I kept getting an error that my web part didn&#8217;t have the <strong>Microsoft.SharePoint.Security.SharePointPermission</strong>.</p>
<p>Well, for some reason the reflection that generated the CAS Policy came back with the wrong description for that permission. It used just &#8216;SharePointPermission&#8217;, but the CAS Policy needs the full strong name.</p>
<p>On looking at WSPBuilder I found that I could specify my own file containing additional permissions:</p>
<p><code>WSPBuilder.exe -WSPName CreateNewDocumentWebPart.wsp -CustomCAS CasPolicy.txt</code></p>
<p>That file contained a declaration of a classes that implement the <strong>IPermission</strong> interface. This include the <strong>SharePointPermission</strong> using the full strong name:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/08/CAS-Policy-file.PNG"><img class="alignnone size-medium wp-image-1610" title="CAS Policy file" src="http://www.novolocus.com/wp-content/uploads/2009/08/CAS-Policy-file-300x20.PNG" alt="CAS Policy file" width="300" height="20" /></a></p>
<p>(There are others here; I was experimenting)</p>
<p>WSPBuilder then created the Manifest file with my permissions:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/08/Automatic-AND-my-CAS-Policy.PNG"><img class="alignnone size-medium wp-image-1612" title="Automatic AND my CAS Policy" src="http://www.novolocus.com/wp-content/uploads/2009/08/Automatic-AND-my-CAS-Policy-300x122.PNG" alt="Automatic AND my CAS Policy" width="300" height="122" /></a></p>
<p>And that worked; all my permissions exceptions went away. My web part worked without elevating trust for my entire farm, or putting my assembly in the GAC (which gives the whole assembly Full Trust).</p>
<p>Kudos to <a href="http://twitter.com/einaros">@Einaros</a> for pointing me toward the right declaration for the <strong>Microsoft.SharePoint.Security.SharePointPermission</strong><a href="http://www.novolocus.com/wp-content/uploads/2009/08/Automatic-AND-my-CAS-Policy.PNG"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/08/13/wspbuilder-and-cas-policies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding CSS links to your SharePoint pages or code…</title>
		<link>http://www.novolocus.com/2009/07/20/adding-css-links-to-your-pages-or-code/</link>
		<comments>http://www.novolocus.com/2009/07/20/adding-css-links-to-your-pages-or-code/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 11:14:29 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSSRegistration]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1601</guid>
		<description><![CDATA[I love Twitter &#8211; you get some though provoking questions on it. Thomas Resing asked the other day:
How are you applying styles to your custom web parts in #SharePoint? using CSSClass property, stuck on deploying css &#60;Link&#62; tag in the head
Well, for pages themselves you have the CSSRegistration control. It&#8217;s an ASP.NET control, and looks [...]]]></description>
			<content:encoded><![CDATA[<p>I love Twitter &#8211; you get some though provoking questions on it. <a href="http://twitter.com/resing">Thomas Resing</a> asked the other day:</p>
<blockquote><p>How are you applying styles to your custom web parts in <a title="#SharePoint" href="http://twitter.com/search?q=%23SharePoint">#SharePoint</a>? using CSSClass property, stuck on deploying css &lt;Link&gt; tag in the head</p></blockquote>
<p>Well, for pages themselves you have the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.cssregistration.aspx"><strong>CSSRegistration </strong></a>control. It&#8217;s an ASP.NET control, and looks something like:</p>
<p><code>&lt;SharePoint:CssRegistration name=<span>"/_layouts/myBrand/SomeStyle.css"</span> runat=<span>"server"</span>/&gt;</code></p>
<p>This control registers the URL with the page, but doesn&#8217;t emit anything. That&#8217;s controlled by the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.csslink.aspx"><strong>CssLink</strong> </a>control:</p>
<p><code>&lt;Sharepoint:CssLink runat=<span>"server"</span> /&gt;</code></p>
<p>It actually outputs the &lt;link&gt; elements, and this means that you can have a <strong>CSSRegistration</strong> control low down in the page (in a <strong>Content</strong> control, for example) and you can still output it in the &lt;head&gt; of your page. There&#8217;s a <a href="http://www.cleverworkarounds.com/2007/10/08/sharepoint-branding-how-css-works-with-master-pages-part-1/">good post about this</a> on CleverWorkarounds. </p>
<p>So, could we use that control? Well, we should be able to instantiate one &#8211; except it turns out that we don&#8217;t have to. We can just use the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.cssregistration.register.aspx"><strong>CSSRegistration.Register()</strong> </a>static method &#8211; something like:</p>
<p><code>protected override void CreateChildControls(){<br />
CssRegistration.Register("/_layouts/myBrand/SomeStyle.css");<br />
}</code></p>
<p>Job done&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/07/20/adding-css-links-to-your-pages-or-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Relating BDC entities for Search Indexing?</title>
		<link>http://www.novolocus.com/2009/07/17/relating-bdc-entities-for-search-indexing/</link>
		<comments>http://www.novolocus.com/2009/07/17/relating-bdc-entities-for-search-indexing/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 15:18:41 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BDC]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1590</guid>
		<description><![CDATA[I think I might have come across a problem with using the BDC to index entity data in legacy systems. I&#8217;m sure I can&#8217;t be the first person to have hit this problem, but I can&#8217;t find a solution. Thus, I thought I&#8217;d blog it so other folks might be aware of it, and to [...]]]></description>
			<content:encoded><![CDATA[<p>I think I might have come across a problem with using the BDC to index entity data in legacy systems. I&#8217;m sure I can&#8217;t be the first person to have hit this problem, but I can&#8217;t find a solution. Thus, I thought I&#8217;d blog it so other folks might be aware of it, and to open the problem up to suggestions.</p>
<p>I&#8217;m not sure I can describe the system I&#8217;m actually working on, so I&#8217;m going to use a slightly contrived example&#8230;<span id="more-1590"></span></p>
<p>We&#8217;ve got data in a SQL server database, and we want to expose this via the BDC. In particular, we want to expose the data to SharePoint search.</p>
<p>In my contrived example we&#8217;ve got a couple of entities &#8211; <em>Person</em> and <em>JobTitle. </em>A <em>Person</em> entity has a JobTitle. In the database it might look something like:</p>
<p>Person:</p>
<table class="displayTable">
<tbody>
<tr>
<th>PersonID</th>
<th>Name</th>
<th>JobTitleID</th>
<th>LastUpdate</th>
</tr>
<tr>
<td>4</td>
<td>Jane Doe</td>
<td>3</td>
<td>2009-05-21 12:01</td>
</tr>
<tr>
<td>5</td>
<td>John Smith</td>
<td>1</td>
<td>2009-05-21 12:05</td>
</tr>
<tr>
<td>6</td>
<td>John Smith</td>
<td>2</td>
<td>2009-05-21 12:10</td>
</tr>
</tbody>
</table>
<p>Job Title:</p>
<table  class="displayTable">
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>LastUpdate</th>
</tr>
<tr>
<td>1</td>
<td>Painter</td>
<td>2009-03-21 12:00</td>
</tr>
<tr>
<td>2</td>
<td>Plumber</td>
<td>2009-03-19 12:32</td>
</tr>
<tr>
<td>3</td>
<td>Tailor</td>
<td>2009-02-21 10:21</td>
</tr>
</tbody>
</table>
<p>Clearly, <em>JobTitleID</em> is the foreign key to the <em>JobTitle</em> table. We&#8217;re also using a Last Updated date/time to allow use to <a href="http://www.lightningtools.com/bdc-meta-man/bdc-incremental-crawls.aspx">incrementally index the database with the BDC</a>.</p>
<p>Now, you&#8217;ll note that we&#8217;ve got 2 people called John Smith. I do mean that we&#8217;ve got two people, not that John Smith has two jobs. What I&#8217;d like to be able to do, then, is search for &#8220;John Smith Painter&#8221; and get one record, or &#8220;John Smith Plumber&#8221; and get the other. In short, the <em>Person</em> entity is the important one; <em>Job Title</em> is just a look-up.</p>
<p>Unfortunately, while we can index these tables via the BDC, essentially the relationship is lost. A Search for &#8220;John Smith Painter&#8221; would return 2 matches for the &#8220;John Smith&#8221; part (our two people) and 1 match for the &#8220;Painter&#8221; part (our job title).</p>
<p>Ideally we could denormalised this database structure, and store the person&#8217;s job against their record directly. Sadly, for the system we&#8217;re working with this isn&#8217;t really an option.</p>
<p>So, what I can&#8217;t figure out is how to get the BDC to index our <em>Person</em> entity and related entity data as a reference to our <em>Person</em> record. I don&#8217;t know if anyone has any ideas, but I&#8217;d come up with:</p>
<ul>
<li>Denormalise the data (we can&#8217;t really do for certain relationships)</li>
<li>Build a separate ASP.NET web site to display our data and index that (but would screw up incremental index)</li>
<li>Write a custom protocol handler (complex, scary, and probably expensive) (<a href="http://www.codeplex.com/MOSSPH">Although this codeplex project might help</a>)</li>
</ul>
<p>If anyone has other suggestions or tips, let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/07/17/relating-bdc-entities-for-search-indexing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Programmatically figure out the Email address of a list</title>
		<link>http://www.novolocus.com/2009/07/09/programmatically-figure-out-the-email-address-of-a-list/</link>
		<comments>http://www.novolocus.com/2009/07/09/programmatically-figure-out-the-email-address-of-a-list/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 13:58:17 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[SPList]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1587</guid>
		<description><![CDATA[I like mail enabled lists &#8211; they&#8217;re not perfect, but they are nice, and most folks can handle working email.
Sometimes, though, you want to programmatically create and enable these lists. That&#8217;s cool &#8211; but how do you figure out the email address of the list afterward?
You can get the first part of the address from [...]]]></description>
			<content:encoded><![CDATA[<p>I like mail enabled lists &#8211; they&#8217;re not perfect, but they are nice, and most folks can handle working email.</p>
<p>Sometimes, though, you want to <a href="http://www.novolocus.com/2009/04/15/programmatically-create-and-configure-mail-enabled-lists/">programmatically create and enable these lists</a>. That&#8217;s cool &#8211; but how do you figure out the email address of the list afterward?</p>
<p>You can get the first part of the address from the <strong>SPList</strong> object&#8217;s <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.emailalias.aspx"><strong>EmailAlias</strong> </a>property. But that&#8217;s only the bit before the &#8216;@&#8217; sign &#8211; what about the end of the address? Well, you get that from the farm:</p>
<p><code>emailAlias = list.EmailAlias + "@" + SPFarm.Local.Services.GetValue&lt;SPIncomingEmailService&gt;("").ServerDisplayAddress;</code></p>
<p>This gets the rest of the address (in my case &#8217;sharepoint.virtual.local&#8217;). Job done.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/07/09/programmatically-figure-out-the-email-address-of-a-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Control the RSS Feed Settings on an SPList via the API</title>
		<link>http://www.novolocus.com/2009/07/08/control-the-rss-feed-settings-on-an-splist-via-the-api/</link>
		<comments>http://www.novolocus.com/2009/07/08/control-the-rss-feed-settings-on-an-splist-via-the-api/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 11:48:53 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[SPList]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1577</guid>
		<description><![CDATA[Tobias Zimmergren tweeted today asking
Anyone got recommendations to how you modify RSS-Settings for an SPList object using the API?
Good question. The SPList object does have a property EnableSyndication that gets or sets whether an RSS feed is available. There is also an property &#8216;AllowRssFeeds&#8217;, but it is, apparently, read only.
So, you can set whether one is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zimmergren.net/default.aspx">Tobias Zimmergren</a> tweeted today asking</p>
<blockquote><p>Anyone got recommendations to how you modify RSS-Settings for an SPList object using the API?</p></blockquote>
<p>Good question. The <strong>SPList</strong> object does have a property <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.enablesyndication.aspx"><strong>EnableSyndication</strong></a> that gets or sets whether an RSS feed is available. There is also an property <strong>&#8216;AllowRssFeeds&#8217;</strong>, but it is, apparently, read only.</p>
<p>So, you can set whether one is allowed or not &#8211; but there are a lot more settings. What about controlling them programmatically? <span id="more-1577"></span></p>
<p>I mean, the settings page in SharePoint looks like this:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/07/RSS-Settings-Page.PNG"><img class="alignnone size-medium wp-image-1578" title="RSS Settings Page" src="http://www.novolocus.com/wp-content/uploads/2009/07/RSS-Settings-Page-300x227.PNG" alt="RSS Settings Page" width="300" height="227" /></a></p>
<p>Where are those settings? Well, looking in <a href="http://www.codeplex.com/spm">SharePoint Manager </a>(fantastic tool) we can see:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/07/RSS-in-SharePoint-Manager.PNG"><img class="alignnone size-medium wp-image-1579" title="RSS in SharePoint Manager" src="http://www.novolocus.com/wp-content/uploads/2009/07/RSS-in-SharePoint-Manager-136x300.PNG" alt="RSS in SharePoint Manager" width="136" height="300" /></a></p>
<p>These settings are actually properties on the Root Folder of the <strong>SPList </strong>(i.e. <strong>SPList.RootFolder.Properties</strong>). To check this I wrote some code to look through the properties and output them to the console:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/07/Code-to-output-properties.PNG"><img class="alignnone size-medium wp-image-1580" title="Code to output properties" src="http://www.novolocus.com/wp-content/uploads/2009/07/Code-to-output-properties-300x94.PNG" alt="Code to output properties" width="300" height="94" /></a></p>
<p>And this output:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/07/Root-Folder-Properties.PNG"><img class="alignnone size-medium wp-image-1581" title="Root Folder Properties" src="http://www.novolocus.com/wp-content/uploads/2009/07/Root-Folder-Properties-300x216.PNG" alt="Root Folder Properties" width="300" height="216" /></a></p>
<p>So, what are the RSS specific properties (there are plenty of other properties in the RootFolder &#8211; <a href="http://www.novolocus.com/2009/04/15/programmatically-create-and-configure-mail-enabled-lists/">email enabled list settings</a>, for example):</p>
<ul>
<li><strong>vti_rss_ChannelTitle</strong> (string) &#8211; The Name of the Rss feed</li>
<li><strong>vti_rss_ChannelImageUrl</strong> (url as a string) &#8211; the url of the image to use in the RSS feed</li>
<li><strong>vti_rss_ChannelDescription</strong> (string) &#8211; The description of the RSS feed.</li>
<li><strong>vti_rss_ItemLimit</strong> (int) &#8211; the maximum number of items in the feed</li>
<li><strong>vti_rss_DayLimit</strong> (int) &#8211; the maximum number of days to include items for.</li>
<li><strong>vti_rss_DocumentAsLink</strong> (bool as 0 or 1) &#8211; Link Rss Items directly to their files? If 1, the title of the Rss Item links directly to the file</li>
<li><strong>vti_rss_DocumentAsEnclosure</strong> (bool as 0 or 1) &#8211; Include file enclosures for items in the feed? If 1, the Rss Item contains a link to the file.</li>
<li><strong>vti_rss_DisplayRssIcon</strong> (bool as 0 or 1) &#8211; Unknown. Doesn&#8217;t seem to do anything</li>
<li><strong>vti_rss_DisplayOnQuickLaunch </strong>(bool as 0 or 1) &#8211; Unknown. Doesn&#8217;t seem to do anything.</li>
<li><strong>vti_rss_LimitDescriptionLength</strong> (bool as 0 or 1) &#8211; Truncate multi-line text fields to 256 characters?</li>
</ul>
<p>So, you can set those values and change your RSS settings. Should all be pretty obvious now. Don&#8217;t forget to do RootFolder.Update() when you&#8217;ve changed the properties&#8230;</p>
<p><strong>EDIT:</strong> Tobias <a href="http://www.zimmergren.net/archive/2009/07/08/using-the-object-model-to-access-and-change-rss-settings-on-a-sharepoint-list.aspx">blogged about this himself too</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/07/08/control-the-rss-feed-settings-on-an-splist-via-the-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rounded Corners on Web Parts</title>
		<link>http://www.novolocus.com/2009/06/30/rounded-corners-on-web-parts/</link>
		<comments>http://www.novolocus.com/2009/06/30/rounded-corners-on-web-parts/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 11:40:20 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Rounded Corners]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1562</guid>
		<description><![CDATA[The Holy Grail of SharePoint branding - at least as far as I&#8217;m concerned &#8211; is rounded corners on Web Parts. Every design that comes in has this at first. As mentioned yesterday there are examples of doing this for the web part&#8217;s title - I&#8217;ve done this using Madalina&#8217;s instructions and Heather Solomon has some instructions too.
However, as far as [...]]]></description>
			<content:encoded><![CDATA[<p>The Holy Grail of SharePoint branding - at least as far as I&#8217;m concerned &#8211; is rounded corners on Web Parts. Every design that comes in has this at first. As mentioned yesterday there are examples of doing this for the web part&#8217;s title - <a href="http://www.novolocus.com/2008/10/09/rounded-corners-are-cool-in-sharepoint-apparently/">I&#8217;ve done this</a> using <a href="http://madalina.blog.com/2705257/">Madalina&#8217;s instructions</a> and <a href="http://www.heathersolomon.com/blog/articles/brandsppart3a.aspx">Heather Solomon has some instructions too</a>.</p>
<p>However, as far as I know nobody has yet figured out a way of putting rounded corners on the bottom corners of web parts. The HTML they have does not suit them to do this via CSS. The only idea I&#8217;ve had previously was to use <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.adapters.controladapter.aspx"><strong>ControlAdapter</strong></a>s to modify the output of of the Web Part itself. And I&#8217;m pretty sure you&#8217;d have to write an adapter per web parts. That kind of sucks; no customer is going to be in a hurry to pay for that.</p>
<p>Well, when I was looking at <a href="http://www.novolocus.com/2009/06/29/rounded-corners-on-web-part-zones/">putting borders around an entire web part zone</a>, I had a thought. What we really need to do is insert elements into our page. jQuery can do that sort of thing. Could I use jQuery to find each web part and wrap some tags around it?<span id="more-1562"></span></p>
<p>Looking in the HTML produced for a page, I noticed that web parts all seem to exist in a table cell with an ID that begins &#8216;<em>MSOZoneCell_WebPart</em>&#8216; so I tried querying for that, and wrapping it in DIV tags (the same structure as used yesterday for the whole zone):</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Jquery-to-put-corners-around-web-parts.PNG"><img class="alignnone size-medium wp-image-1564" title="Jquery to put corners around web parts" src="http://www.novolocus.com/wp-content/uploads/2009/06/Jquery-to-put-corners-around-web-parts-300x150.PNG" alt="Jquery to put corners around web parts" width="300" height="150" /></a></p>
<p>Erm, this worked (Image below is just one web part zone):</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Individual-Web-part-borders.PNG"><img class="alignnone size-medium wp-image-1566" title="Individual Web part  borders" src="http://www.novolocus.com/wp-content/uploads/2009/06/Individual-Web-part-borders-300x246.PNG" alt="Individual Web part  borders" width="300" height="246" /></a></p>
<p>Clearly, that style sucks. And you&#8217;d want to work on the styles of the web parts themselves &#8211; removing borders and the like. And I think that having separately styled &#8216;titles&#8217; and &#8216;bodies&#8217; might be&#8230; awkward. But those are borders around individual web parts. They do show up in <em>Edit</em> mode, and they do move when you drag the web parts around:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/jQuery-corners-in-Edit-mode.PNG"><img class="alignnone size-medium wp-image-1567" title="jQuery corners in Edit mode" src="http://www.novolocus.com/wp-content/uploads/2009/06/jQuery-corners-in-Edit-mode-300x290.PNG" alt="jQuery corners in Edit mode" width="300" height="290" /></a></p>
<p>Unfortunately, I do seem to be getting a JavaScript Error now. When I open it up to look at it I see:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Error-from-jQuery-Webpart.PNG"><img class="alignnone size-medium wp-image-1568" title="Error from jQuery Webpart" src="http://www.novolocus.com/wp-content/uploads/2009/06/Error-from-jQuery-Webpart-300x194.PNG" alt="Error from jQuery Webpart" width="300" height="194" /></a></p>
<p>I&#8217;m pretty sure I&#8217;ve never written 120 million lines of code, so I&#8217;m not quite sure what&#8217;s going on here. It doesn&#8217;t seem to cause any problems though. I don&#8217;t know if somone can take this prototype on and solve that one &#8211; but I can&#8217;t find the problem. It sounds very similar to <a href="http://dev.jquery.com/ticket/4765">this bug report</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/06/30/rounded-corners-on-web-parts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rounded Corners on Web Part Zones</title>
		<link>http://www.novolocus.com/2009/06/29/rounded-corners-on-web-part-zones/</link>
		<comments>http://www.novolocus.com/2009/06/29/rounded-corners-on-web-part-zones/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 10:50:10 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Rounded Corners]]></category>
		<category><![CDATA[Web Part Zones]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1553</guid>
		<description><![CDATA[Curiously, one of my more popular blog posts is about putting rounded corners on things in SharePoint. It does seem that this is a pretty popular question. As a side note, Heather Solomon has a post about doing this for web part titles, though I followed Madalina&#8217;s instructions.
Anyway, one design requirement that come up repeatedly [...]]]></description>
			<content:encoded><![CDATA[<p>Curiously, one of my more popular blog posts is about <a href="http://www.novolocus.com/2008/10/09/rounded-corners-are-cool-in-sharepoint-apparently/">putting rounded corners on things in SharePoint</a>. It does seem that this is a pretty popular question. As a side note, Heather Solomon has a post about <a href="http://www.heathersolomon.com/blog/articles/brandsppart3a.aspx">doing this for web part titles</a>, though <a href="http://madalina.blog.com/2705257/">I followed Madalina&#8217;s instructions</a>.</p>
<p>Anyway, one design requirement that come up repeatedly is rounded borders on Web Parts. I swear, it comes up with every design &#8211; and it isn&#8217;t possible (although I have an idea &#8211; more on that tomorrow). What you can do, though, is have a rounded border about the entire web part zone&#8230;<span id="more-1553"></span></p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/2-Web-Parts-in-two-Zones.PNG"><img class="alignnone size-medium wp-image-1554" title="2 Web Parts in two Zones" src="http://www.novolocus.com/wp-content/uploads/2009/06/2-Web-Parts-in-two-Zones-300x102.PNG" alt="2 Web Parts in two Zones" width="300" height="102" /></a></p>
<p>Of course, the problem with this is that if you put two web parts in one zone you get something like the following:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/2-Web-Parts-in-one-Zone.PNG"><img class="alignnone size-medium wp-image-1555" title="2 Web Parts in one Zone" src="http://www.novolocus.com/wp-content/uploads/2009/06/2-Web-Parts-in-one-Zone-300x217.PNG" alt="2 Web Parts in one Zone" width="300" height="217" /></a></p>
<p>Actually, that can sometimes work quite well, but it&#8217;s something else to consider when you (or your users) are laying out their web parts. Still, it&#8217;s pretty easy &#8211; here are the image files used for the border (I put them into a folder in LAYOUTS):</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Files-used.PNG"><img class="alignnone size-medium wp-image-1556" title="Files used" src="http://www.novolocus.com/wp-content/uploads/2009/06/Files-used-300x141.PNG" alt="Files used" width="300" height="141" /></a></p>
<p>I then put a whole bunch of DIV tags into my page for the borders. I don&#8217;t like having all of them, but it&#8217;s a fairly standard way of doing this (browsers &#8211; please support CSS for corner radius soon).</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/DIV-tags-for-corners.PNG"><img class="alignnone size-medium wp-image-1557" title="DIV tags for corners" src="http://www.novolocus.com/wp-content/uploads/2009/06/DIV-tags-for-corners-300x130.PNG" alt="DIV tags for corners" width="300" height="130" /></a></p>
<p>Yuck! Lots of DIVs, but combined with these CSS Styles &#8230;</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Styles.PNG"><img class="alignnone size-medium wp-image-1558" title="Styles" src="http://www.novolocus.com/wp-content/uploads/2009/06/Styles-300x109.PNG" alt="Styles" width="300" height="109" /></a></p>
<p>&#8230; it puts our border around our web part zone. Obviously, for a real system you&#8217;d use a nice looking border &#8211; mine is for prototype only.</p>
<p>One issue that remains, though, is what happens if there are no web parts in the web part zone? Well, as it stands you&#8217;d have a nice empty box which would shrink to its minimum size, as there are not contents. This isn&#8217;t ideal &#8211; if it&#8217;s empty, we&#8217;d rather not see it at all. SharePoint seems to deal with this for square borders using the <a href="http://www.novolocus.com/2008/11/07/what-is-msolayouts_makeinvisibleifempty/">MSO_Layouts_MakeInvisibleIfEmpty() </a>Javascript function. JavaScript? Pah! Quaint and old school &#8211; I used a bit of jQuery:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/JQuery.PNG"><img class="alignnone size-medium wp-image-1559" title="JQuery" src="http://www.novolocus.com/wp-content/uploads/2009/06/JQuery-300x70.PNG" alt="JQuery" width="300" height="70" /></a></p>
<p>What this code does is get the innermost DIV tag of every bordered area. If that DIV tag doesn&#8217;t have any children, we find the first parent DIV tag at the &#8216;top&#8217; of my set of nested DIVs, and hide it! And that works nicely:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/No-Leftovers.PNG"><img class="alignnone size-medium wp-image-1560" title="No Leftovers" src="http://www.novolocus.com/wp-content/uploads/2009/06/No-Leftovers-300x139.PNG" alt="No Leftovers" width="300" height="139" /></a></p>
<p>Next up, <a href="http://www.novolocus.com/2009/06/30/rounded-corners-on-web-parts/">I&#8217;ll take a look at borders on web parts themselves</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/06/29/rounded-corners-on-web-part-zones/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Automatically add themes to the SPThemes.xml file</title>
		<link>http://www.novolocus.com/2009/06/25/automatically-add-themes-to-the-spthemes-xml-file/</link>
		<comments>http://www.novolocus.com/2009/06/25/automatically-add-themes-to-the-spthemes-xml-file/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 09:45:15 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>

		<guid isPermaLink="false">http://www.novolocus.com/?p=1536</guid>
		<description><![CDATA[I&#8217;m not sure I&#8217;ll use themes again over the AlternateCssUrl again in a hurry, but I did decide to take a look at the 10 example themes Microsoft Released in March. I&#8217;ll blog about how they look &#8211; sometime! (The short answer &#8211; some good, some bad, some awful!)
Anyway, I was interested that the themes [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not sure I&#8217;ll use themes again over the<a href="http://www.novolocus.com/2008/11/10/where-to-put-css-when-branding/"> AlternateCssUrl </a>again in a hurry, but I did decide to take a look at the<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=0A87658F-20B8-4DCC-AD7A-09AD22641F3A&amp;displaylang=en"> 10 example themes Microsoft Released in March</a>. I&#8217;ll blog about how they look &#8211; sometime! (The short answer &#8211; some good, some bad, some awful!)</p>
<p>Anyway, I was interested that the themes could all be activated as features. This rather kept with <a href="http://www.novolocus.com/2009/02/12/feature-stapling-for-branding/">my feeling on how branding</a> should be deployed.</p>
<p>However, some of the themes (though not all) were suddenly available in the &#8216;Site Themes&#8217; page of my SharePoint system. I knew from experience that this isn&#8217;t something that &#8216;just happens&#8217; &#8211; previously, I&#8217;ve done it by hand.</p>
<p><strong>EDIT: See the comments &#8211; they describe an possible pit fall, but both have articles about how to do the same thing&#8230;</strong><span id="more-1536"></span></p>
<p>I became curious, so I opened up Reflector. I found that there is a method called when the feature is installed to update the SPThemes.xml file:</p>
<p><a href="http://www.novolocus.com/wp-content/uploads/2009/06/Add-Themes-Method.PNG"><img class="alignnone size-medium wp-image-1537" title="Add Themes Method" src="http://www.novolocus.com/wp-content/uploads/2009/06/Add-Themes-Method-300x220.PNG" alt="Add Themes Method" width="300" height="220" /></a></p>
<p>ModificationType is just a private enumeration to tell you whether you are adding or removing an entry from the SPThemes file. This code is called from within a <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfeaturereceiver.aspx">Feature Receiver</a> during  <span style="text-decoration: line-through;">FeatureActivated</span> <span style="text-decoration: line-through;">FeatureInstalling</span> (need to check, see comments below)</p>
<p>Anyway, I&#8217;ll remember this in case I should need to do similar. Obviously, the original code is probably simpler than the decompiled stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.novolocus.com/2009/06/25/automatically-add-themes-to-the-spthemes-xml-file/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
