Pimp Your IDE: Visual Studio 2010 Themes and Skins

by Ради Атанасов 16. May 2010 13:35

For those who know me, I have always been a HUGE fan of customizing my development environment. Well now with Visual Studio 2010 we can do more than what we could do with VS 2008… I’ve always known that, but now I found the right tool to help me do it.

Visual Studio Color Theme Editor lets you change the colors of VS 2010 and save a set as a “theme”. Here is my first VS 2010 dark theme:

Elite Dark

clip_image001

Just install the extension and open my theme and you are ready to go!

Download Visual Studio Color Theme Editor

Download my theme: Elite Dark

UPDATE: My initial version had dark shades on the grid, I made them a bit lighter. ZIP file updated.

Tags: , ,

English

Using LINQ to XML to process SharePoint web service responses in Silverlight

by Ради Атанасов 18. March 2010 11:53

Since working with LINQ to XML, I’ve totally fallen in love with it and could never go back to working with the XmlDocument objects.

Here are a few code snippets that can help you out. It is so simple once you get a hang of it.

GetListItems() – this Lists.asmx method returns the following response:

<listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<rs:data ItemCount="13">
   <z:row ... ows_ContentType="Task" ows_Title="New Task 1" ... />
   ... more rows here
</rs:data>
</listitems>

To get the value of the title into a List<string> object:

private List<string> ProcessListResults(SPListsWS.GetListItemsCompletedEventArgs e)
{
    string result = e.Result.ToString();
 
    XNamespace ns = "#RowsetSchema";
    XElement results = new XElement(e.Result);
 
    var listItems = from x in results.Descendants(ns + "row")
                    where x.Attribute("ows_Title") != null
                    select x;
 
    List<string> itemsList = new List<string>();
 
    foreach (var item in listItems)
    {
        string title = item.Attribute("ows_Title").Value;
        itemsList.Add(title);
    }
    return itemsList;
}

GetUserInfo() – this method is inside usergroup.asmx and gives us information regarding a user in an SPSite object. The response:

<GetUserInfo xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
  <User ID="7" Sid="S-1-5-21-347908140-582334945-263120918-1111" Name="Radi"
    LoginName="DEV\radi" Email="" Notes="" IsSiteAdmin="False"
    IsDomainGroup="False" />
</GetUserInfo>

 

To get the LoginName:

public static string GetLoginFromServiceResponse(XElement result)
{
    XNamespace ns = "http://schemas.microsoft.com/sharepoint/soap/directory/";
 
    XName xUser = XName.Get("User", ns.NamespaceName);
    XName xUserInfo = XName.Get("GetUserInfo", ns.NamespaceName);
 
    XElement user = result.Element(xUser);
 
    if (user != null) {  return user.Attribute("LoginName").Value; }
 
    return null;
}

The passed in “result” is derived from e.Result.ToString().

Hope this helps!

Tags: , , , ,

English

SharePoint meets LINQ to XML: Building a CAML Query and calling Lists.asmx

by Ради Атанасов 18. March 2010 10:20

I’ve been playing around with LINQ to XML and Silverlight recently, and it is absolutely awesome! The amount of code you have to write compared to working with XML DOM objects like XmlDocument is extremely minimised.

Here is an example on calling the GetListItems() method of Lists.asmx. I am returning the top 100 items in a Task list that are created by a particular user. This code example should be compatible for both WSS v3 and MSF v4.

XElement query = new XElement("Query",
        new XElement("Where",
            new XElement("Eq",
                new XElement("FieldRef", new XAttribute("Name", "Author"), new XAttribute("LookupId", "True")),
                new XElement("Value", new XAttribute("Type", "User"), userID)
)));


XElement queryOptions = new XElement("QueryOptions");
XElement viewFields = new XElement("ViewFields");

_listService.GetListItemsAsync("Tasks", null,
    query, viewFields, "100", queryOptions, null, null);

userID is the SharePoint user value within the current SPSite. You can get this with the usergroup.asmx service.

Hope this helps!

Tags: , , , ,

English

Forcing the DIP to load when a Word Document loads from SharePoint

by Ради Атанасов 21. February 2010 07:47

I was working on a project and I had custom content types defined in a feature. These content types had document templates, and I wanted to control the Document Information Panel (DIP) when a document is opened in Word.

The following code snippet takes an SPContentType object and adds a custom XSN element to the content types XmlDocuments collection. Setting the openByDefault value to “True” will force the DIP to open when the document loads. I use a FeatureReceiver to run this code against a newly provisioned Content Type.

public static void ConfigureContentTypes(SPContentType ct)
{
    XmlDocument doc = GetCustomXsnDocument();
 
    ct.XmlDocuments.Add(doc);
    ct.Update(true);
}
 
private static XmlDocument GetCustomXsnDocument()
{
    XmlDocument doc = new XmlDocument();
    
    string xml = "<customXsn xmlns=\"http://schemas.microsoft.com/office/2006/metadata/customXsn\"><xsnLocation></xsnLocation><cached>True</cached><openByDefault>True</openByDefault><xsnScope></xsnScope></customXsn>";
 
    doc.LoadXml(xml);
    return doc;
}

You can find information about the child CustomXsn elements on this MSDN link: Content Type Document Information Panel Schema

Hope this helps.

Tags: , , ,

English

SharePoint 2007 list forms under the hood – Part 2

by Ради Атанасов 20. February 2010 13:49

In Part 1 of this series I looked at replacing the “NewFormUrl”, “EditFormUrl” and “DisplayFormUrl” properties of the Content Type object to change the forms that SharePoint uses to display list item information. In this second part I will discuss how we can replace the actual Rendering Templates to achieve the same goals.

This is how Rendering Templates work:

Each item in a SharePoint list is of a certain Content Type. In most cases items are either an “Item” Content Type or a “Document” Content Type depending on the Base Type of the list. Usually as developers and customisers we create additional Content Types that make sense to the business, for example Invoices, Quotes, Proposals, etc.

Each Content Type has “New”, “Edit” and “Display” forms for displaying and collecting data related to the content type item. Each one of these 3 forms has a “Form Rendering Template” that defines the HTML markup and controls that will render for the forms.

These Rendering Templates are defined in the _CONTROLTEMPLATES folder. Most other objects in SharePoint have Rendering Templates which are defined in DefaultTemplates.ascx, check out the Toolbar, ListFieldIterator, etc. The DocumentLibraryForm is defined in DefaultTemplates.ascx:

<SharePoint:RenderingTemplate ID="DocumentLibraryForm" runat="server">
    <Template>
        <SharePoint:InformationBar runat="server"/>
        <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" 
        RightButtonSeparator="" runat="server">
            <Template_RightButtons>
                <SharePoint:SaveButton runat="server"/>
                <SharePoint:GoBackButton runat="server"/>
            </Template_RightButtons>
        </wssuc:ToolBar>
        <SharePoint:FormToolBar runat="server"/>
        <SharePoint:FormComponent TemplateName="DocumentLibraryFormCore" 
        runat="server"/>
    </Template>
</SharePoint:RenderingTemplate>

 

This rendering template calls other “FormCompontent” objects and their Rendering Tempaltes – very similar to PHP…

Our goal is to replace these Rendering Templates with our own, so we modify what end users see in the New, Edit and Display scenarios.

We can “tell” Content Types to use our own Rendering Tempaltes by two ways: including XML in the Content Type Definition, or Using code.

Option 1:

Content Type definitions in features allow you to set XmlDocument elements:

<!-- Document Content Type -->
<ContentType ID="0x0101006BD6DAD38F7947799A6F2EE72F5C3C24"
    Name="TemporaryContentType"
    Group="Custom Content Types"
    Description="">
    <FieldRefs>
        <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" />
    </FieldRefs>
    <XmlDocuments>
        <XmlDocument 
        NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
            <FormTemplates 
            xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
                <Display>MyCustomForm</Display>
                <Edit>MyCustomForm</Edit>
                <New>MyCustomForm</New>
            </FormTemplates>
        </XmlDocument>
    </XmlDocuments>
</ContentType>

With the above FormTemplates element under XmlDocument I have specified that the custom content type should use the custom Rendering Template MyCustomForm for rendering the New, Edit and Display forms.

To create this Rendering Template, create your own ASCX file to store it, use a feature to deploy it to the CONTROLTEMPLATES folder, and then add the XmlDocuments element to your Content Type definition as demonstrated above. Here is a basic Rendering Template that should go in a custom ASCX file, you can name it however you wish, SharePoint will “crawl” the folder for all Rendering Templates during the Application Pool start-up sequence.

<SharePoint:RenderingTemplate ID="MyCustomForm" runat="server">
    <Template>
        Hello
    </Template>
</SharePoint:RenderingTemplate>

You can include your own custom ASCX controls in your rendering templates and completely change the SharePoint experience.

In part 1 I explained how the ListFormWebPart gets added to our form pages that get provisioned with the list. This web part is what actually does the work in both options. During load time it checks the Rendering Template name specified in the properties and builds its markup based on that template.

Here is a shot of the TemplateName property where the web part checks the current Content Type and gets its template names:

clip_image002

This leads us to our next option: changing the Template names in code.

Option 2: Using code to change a Content Types Rendering Template.

It’s quite simple - the SPContentType object exposes 3 properties so we can set the template names:

cType.NewFormTemplateName = “MyCustomForm”;
cType.EditFormTemplateName = “MyCustomForm”;;
cType.DisplayFormTemplateName = “MyCustomForm”;
cType.Update(true);

This essentially achieves the same as Option 1 above, but keep in mind that you should most likely push the changes down to child content types – call .Update(true); instead of .Update();

All the best.

Tags: , ,

English

SharePoint 2007 list forms under the hood

by Ради Атанасов 7. February 2010 09:03

This post is the first out of a two-part series, where I look at the way SharePoint list forms work and how we can customise them. Part 1 explains how to use custom ASPX pages for list forms, and Part 2 goes through replacing SharePoint’s default rendering templates with custom ones. At the end of the activity I will provide a code sample with both.

When we provision a list in SharePoint we make an ‘instance’ of it based on a list template. Templates are defined in features, and each feature with a list template will hold a schema.xml file. You can view the schema.xml files of existing list templates in features that come with WSS – CustomList, ContactList, DocumentLibrary, etc. just check the 12\TEMPLATE\FEATURES folder.

At the bottom of the schema.xml files we can see a Form element that defines the ASPX files used during the provisioning of lists:

clip_image002

When a list is provisioned, the platform makes a copy of the physical file defined in the “SetupPath” attribute, stores it in the content DB and names it as specified in the “Url” attribute, and adds a ListFormWebPart to the WebPartZoneID specified. “pages\form.aspx” maps to 12\TEMPLATE\Pages\form.aspx and you could replace these with your own. I have demonstrated CustomList, but other lists and libraries use the rest of the files in there.

All this gets interesting when Content Types are added to lists. Each Content Type can have its _own_ DisplayForm, EditForm or NewForm – and in a single list you can have different forms for different Content Types - This means POWER! Furthermore, the same Content Types used across different lists can have consistent forms.

So how does it work?

The SPContentType class allows you to set the EditFormUrl, DispFormUrl, and NewFormUrl properties:

cType.EditFormUrl = "_layouts/ourprojectfolder/customedit.aspx";

cType.NewFormUrl = "_layouts/ourprojectfolder/customnew.aspx";

cType.DisplayFormUrl = "_layouts/ourprojectfolder/customdisplay.aspx";

If these are set, this is what happens under the hood:

· The “New” button on the toolbar or the Item Context menu takes the user to one of the forms: EditForm.aspx, NewForm.aspx or DispForm.aspx

· During provisioning, the ListFormWebPart is added to each of these forms. Check the WebPartZoneID property – this tells the platform where to add the web part. You can’t go without it – SharePoint complains.

· The ListFormWebPart checks the current SPControlMode (Edit, New, Display) and whether the respective property of the current item’s Content Type is null or empty. This can be seen by examining the source code of the web part with Reflector. It makes a check on this.FormPageUrl (which is obfuscated!):

clip_image003

So what we can see is the navigation items take us to either NewForm.aspx, EditForm.aspx or DispForm.aspx. The ListFormWebPart on that page does a check on the current Content Type and takes us to the current SPControlMode’s form. This is what “this.FormPageUrl” does behind the “obfuscated” scene.

An obvious drawback of such design is the fact that the user is first taken to NewForm.aspx (or any of the others), then an SPUtility.Redirect call is made (essentially Response.Redirect) which results in a second postback for the user. You can see the two requests with Firebug or any other HTTP listener. Apart from that there is some overhead – NewForm.aspx is a web part page (and they aren’t light).

What I currently don’t know is how to set the EditFormUrl, NewFormUrl and DispFormUrl properties in the ContentType definition schema. The “Forms” element is obsolete in WSS v3, so the only current way I know to change forms via CAML is to work with the XmlDocuments element. These two options work in a completely different manner. In Part 2 of this series I will demonstrate how you can set custom rendering templates in features with content types.

Hope this helps.

Tags: , ,

English

About the author

Аз съм консултант, архитект и разработчик на SharePoint решения.

Feeds

Get RSS Feed (Bulgarian)
Get RSS Feed (English)    
Get RSS Feed  (Both)        


Abilitics