I’ve just had a 5 day training on development for SharePoint 2010. We’ve seen some cool stuff, were able to do some Hands on Labs and talk to other SharePoint experts about the new stuff that is coming up.

One of the best things though about this training was the ability to try some stuff out for yourself. The fact that no project managers or customers were bothering me for a week allowed me to finally take the time to look around in the object model, the central admin and the new front end interfaces.

Over the next few week I’ll be publishing some post on the things I’ve tried out.I hope to publish a lot more posts about SP2010 once Beta 2 comes available.

DISCLAIMER: The examples are build on and tested against a Beta 1 build of SharePoint 2010 and a Beta 1 build of Visual Studio 2010, so there is no guarantee this will work on later versions.

One of the things I was eager to try out is the new Document Sets feature. Document Sets allow you to group related documents together and share metadata between those docs. When you view a document set in a library, you are presented with a welcome page that shows the metadata of the set and the contents. The welcome page in itself is something you’re able to customize. So you can add web parts and other controls through the interface or SharePoint Designer to the welcome page.

First let me start by giving you some code you can use to show extra information about the document set in a web part you can place on the welcome page:

try
{
     SPListItem item = SPContext.Current.ListItem;
     DocumentSet set = DocumentSet.GetDocumentSet(item.Folder);
     writer.WriteLine("ContentType: {0}<br/>", item.ContentType.Name);
     writer.WriteLine("Title: {0}<br/>", item.Title);
     writer.WriteLine("WelcomePageUrl: {0}<br/>", set.WelcomePageUrl);
     writer.WriteLine("ItemCount: {0}<br/>", set.Folder.ItemCount);
     writer.WriteLine("Welcomepage Fields:<br/>");
     DocumentSetTemplate template = set.ContentTypeTemplate;
     WelcomePageFieldCollection fields = template.WelcomePageFields;
     foreach (SPField field in fields)
     {
         writer.WriteLine("{0}<br/>", field.Title);
     }
}
catch (Exception)
{ }

First we get a reference to the current List Item through the SPContext. This list item is the main item for the document set that contains the metadata that is pushed into the child documents.

We then can get a reference to the DocumentSet by passing in the SPFolder of the item into a static method of the DocumentSet class. The DocumentSet class is stored in the Microsoft.Office.DocumentManagement.dll in the DocumentSets namespace.

The DocumentSetTemplate in turn contains more information about the fields that are shared or shown on the Welcome page.

In the next post I’ll show you how to provision a document set from a feature. Something that is quite easy to do with the new SharePoint project and item templates for Visual Studio 2010.

In one of our projects we needed to show the Modified date and time value in publishing page.

Not a big deal you would think. The only issue we had when using a FieldValue control is that the time that would be displayed was 1 or 2 hours later than the actual value.

After I changed this to a DateTimeField the difference was gone.

The only thing you need to add is a ControlMode=”Display” attribute to prevent editors from setting their own value in edit mode.

The difference is in the way the value is rendered. The FieldValue control does a ToString() and HtmlEncode on the value. The DateTimeField actually converts the value to local time by using the TimeZone class.

It’s all in the details!

Today I was working on a Dynamics CRM 4.0 Plug-in we’ve developed in the past and I needed to update the plug-in on our CRM server.

When I loaded the assembly in the Plug-in Registration tool I got the following exception:

Unhandled Exception: System.BadImageFormatException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
An attempt was made to load a program with an incorrect format.
  at System.Reflection.Assembly._GetExportedTypes()
  at PluginRegistrationTool.AssemblyReader.RetrievePluginsFromAssembly(String path)
  at PluginRegistrationTool.AssemblyReader.RetrievePluginsFromAssembly(String path)
  at PluginRegistrationTool.RegistrationHelper.RetrievePluginsFromAssembly(String pathToAssembly)
  at PluginRegistrationTool.PluginRegistrationForm.btnLoadAssembly_Click(Object sender, EventArgs e)

Appearently this was due to the fact I was working on a 64 bit environment. When you place the tool in the 64bit folder of the sdk\bin folder, the error doesn’t occur anymore and you’ll be able to succesfully update your plug-in.

When you create two or more animations that work on the same property of an object, Silverlight will only use the last of the defined animations.

By using transforms you’re able to achieve the same effect anyway. For instance, I’ve got a rectangle that slides up and down by using an animation that works on the Canvas.Top property:

<userControl x:Class="TestAnimationTransform.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
 <userControl.Resources>
  <storyboard x:Name="WaveTop" AutoReverse="True" RepeatBehavior="Forever">
	<doubleAnimationUsingKeyFrames x:Name="WaveAnimationTop" BeginTime="00:00:00" Storyboard.TargetName="Rectangle" Storyboard.TargetProperty="(canvas.top)">
		<easingDoubleKeyFrame KeyTime="00:00:00" Value="50">
			<easingDoubleKeyFrame.EasingFunction>
			   <sineEase EasingMode="EaseInOut"/>
		    </easingDoubleKeyFrame.EasingFunction>
	    </easingDoubleKeyFrame>
	    <easingDoubleKeyFrame KeyTime="00:00:10" Value="400">
		   <easingDoubleKeyFrame.EasingFunction>
		       <sineEase EasingMode="EaseInOut"/>
	       </easingDoubleKeyFrame.EasingFunction>
        </easingDoubleKeyFrame>
    </doubleAnimationUsingKeyFrames>
  </storyboard>
 </userControl.Resources>
 <canvas x:Name="LayoutRoot">
  <rectangle x:Name="Rectangle" Fill="Blue" Width="50" Height="50" Canvas.Top="240" Canvas.Left="200">
  </rectangle>
 </canvas>
<userControl>

This will create an effect like this:

If I want to apply an animation that jiggles the rectangle back and forth over the X- and Y-axis, I can’t use the Canvas.Top property anymore. So instead, we’ll add a Transform to the object and animate the properties of the Transform:

<storyboard x:Name="WaveJiggle" AutoReverse="True" RepeatBehavior="Forever">
	<doubleAnimationUsingKeyFrames x:Name="XAnimation" BeginTime="00:00:00" Storyboard.TargetName="TranslateTransform" Storyboard.TargetProperty="X">
		<easingDoubleKeyFrame KeyTime="00:00:00" Value="20">
			<easingDoubleKeyFrame.EasingFunction>
			<sineEase EasingMode="EaseInOut"/>
		</easingDoubleKeyFrame.EasingFunction>
	</easingDoubleKeyFrame>
	<easingDoubleKeyFrame KeyTime="00:00:01" Value="80">
		<easingDoubleKeyFrame.EasingFunction>
		<sineEase EasingMode="EaseInOut"/>
	</easingDoubleKeyFrame.EasingFunction>
</easingDoubleKeyFrame>
</doubleAnimationUsingKeyFrames>
<doubleAnimationUsingKeyFrames x:Name="YAnimation" BeginTime="00:00:00" Storyboard.TargetName="TranslateTransform" Storyboard.TargetProperty="Y">
<easingDoubleKeyFrame KeyTime="00:00:00" Value="20">
	<easingDoubleKeyFrame.EasingFunction>
	<sineEase EasingMode="EaseInOut"/>
</easingDoubleKeyFrame.EasingFunction>
</easingDoubleKeyFrame>
<easingDoubleKeyFrame KeyTime="00:00:01" Value="80">
<easingDoubleKeyFrame.EasingFunction>
<sineEase EasingMode="EaseInOut"/>
</easingDoubleKeyFrame.EasingFunction>
</easingDoubleKeyFrame>
</doubleAnimationUsingKeyFrames>
</storyboard>
<rectangle x:Name="Rectangle" Fill="Blue" Width="50" Height="50" Canvas.Top="240" Canvas.Left="200">
<rectangle.RenderTransform>
<translateTransform X="50" Y="50" x:Name="TranslateTransform"/>
</rectangle.RenderTransform>
</rectangle>

The result of this will look like the following:

We frequently get the question to display the next x upcoming events in a rollup webpart. A content query web part is very suitable for this, but you will needa custom ItemStyle. Below you will find the xsl to display events in the following format:

Example style

The custom itemstyle checks for the difference between all day events, events that span multiple days and checks for start and end times.

To use this itemstyle you will need to add EventDate and EndDate to the CommonViewFields and reference the ddwrt namespace in the top of your xsl:

xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"

And finally here’s the itemstyle:

<xsl:template name="CalendarEvent" match="Row[@Style='CalendarEvent']" mode="itemstyle">
     <xsl:variable name="SafeImageUrl">
        <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
            <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="SafeLinkUrl">
        <xsl:call-template name="OuterTemplate.GetSafeLink">
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="DisplayTitle">
        <xsl:call-template name="OuterTemplate.GetTitle">
            <xsl:with-param name="Title" select="@Title"/>
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
   </xsl:variable>
      <xsl:variable name="LinkTarget">
         <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
   </xsl:variable>
   <xsl:variable name="MultiDayEvent">
       <xsl:choose>
           <xsl:when test="starts-with(@EndDate,substring(@EventDate, 0, 11))">
               0
           </xsl:when>
           <xsl:otherwise>
               1
           </xsl:otherwise>
       </xsl:choose>
   </xsl:variable>
   <xsl:variable name="StartTimeIsEndTime">
       <xsl:choose>
           <xsl:when test="contains(@EndDate,substring(@EventDate, 11, 9))">
               1
           </xsl:when>
           <xsl:otherwise>
               0
           </xsl:otherwise>
       </xsl:choose>
   </xsl:variable>
   <xsl:variable name="DisplayDate">
       <xsl:choose>
           <xsl:when test="$MultiDayEvent = 0">
               <xsl:choose>
                   <xsl:when test="@fAllDayEvent = 0">
                    <xsl:choose>
                           <xsl:when test="$StartTimeIsEndTime = 1">
                               <xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1043 ,'dd-MM-yyyy H:mm')" />
                           </xsl:when>
                           <xsl:otherwise>
                               <xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1043 ,'dd-MM-yyyy H:mm')" /> - <xsl:value-of select="ddwrt:FormatDateTime(string(@EndDate) ,1043 ,'H:mm')" />
                           </xsl:otherwise>
                       </xsl:choose>
                   </xsl:when>
                   <xsl:otherwise>
                    <xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1043 ,'dd-MM-yyyy')" />
                </xsl:otherwise>
               </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
               <xsl:choose>
                   <xsl:when test="@fAllDayEvent = 0">
                       <xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1043 ,'dd-MM-yyyy H:mm')" /> - <xsl:value-of select="ddwrt:FormatDateTime(string(@EndDate) ,1043 ,'dd-MM-yyyy H:mm')" />
                   </xsl:when>
                   <xsl:otherwise>
                       <xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1043 ,'dd-MM-yyyy')" /> - <xsl:value-of select="ddwrt:FormatDateTime(string(@EndDate) ,1043 ,'dd-MM-yyyy')" />
                   </xsl:otherwise>
               </xsl:choose>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:variable>
   <a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}">
        <xsl:value-of select="$DisplayTitle"/>
    </a>
    <xsl:text> - </xsl:text><xsl:value-of select="$DisplayDate"/><br/>
</xsl:template>