Archive

Archive for the ‘ASP.NET’ Category

ASP.NET LinkedListBoxes UserControl

January 5, 2012 Leave a comment

I needed a simple Linked ListBox control for a project but couldnt find one that was available for free so I ended up developing one myself.

I have created a project for it on codeplex and published it. Please feel free to use/modify the control as you require. If you have any suggestions or feedback then please feel free to leave a comment.

The control uses two ListBoxes with two buttons (add, remove) in between that allows you to add and remove items by using some Javascript. The screen shot below shows the control in action:

LinkedListBox UserControl

You can download the complete source code from the link below:

LinkedListBox UserControl sourcecode.

You can also download a sample Visual Studio 2010 project that shows the control in action by going to the project home page and clicking on the Download button:

Project homepage

SharePoint 2010: Custom action that executes custom code

November 21, 2010 18 comments

In 2007 it was possible to create a custom action and then link it to some code.

You did this by first declaring your custom action in an elements.xml file (which you would then deploy as part of a feature):

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="MyCustomAction"
    RegistrationType="List"
    GroupId="ActionsMenu"
    Location="Microsoft.SharePoint.StandardMenu"
    Sequence="1000"
    ControlAssembly="[Fully qualified assembly name]"
    ControlClass="MyNamespace.MyCustomAction">
  </CustomAction>
</Elements>

In the ControlAssembly and ControlClass attributes you specified your custom assembly and your custom class (a WebControl) that contained your custom code.

Then you created your custom WebControl:

public class MyCustomAction : WebControl 
{
    protected override void CreateChildControls() 
    {
        // Do some stuff
    }
}

Using this way we were able able to execute some custom code when someone clicked our custom action.

However, it seems that we cannot use this method in SharePoint 2010 although there are a few workarounds to achieve the same result. Below I will show you a way I used.

To start off with, I created an elements.xml file with the following declaration:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="ContentTypeRibbonCustomization" RegistrationId="10005" RegistrationType="List" Location="CommandUI.Ribbon.ListView" Sequence="95" Title="Run Custom Code">
    <CommandUIExtension>
      <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.List.Settings.Controls._children">
          <Button Id="ContentTypeTest.Button" Image16by16="/_layouts/images/LSTPEND.gif" Image32by32="/_layouts/images/centraladmin_configurationwizards_farmconfiguration_32x32.png" Command="ContentTypeCommand" CommandType="General" Description="Runs some custom Code" TemplateAlias="o2" Sequence="95" LabelText="Perform My Action"/>
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler Command="ContentTypeCommand" CommandAction="/MyWeb/_layouts/CustomPages/MyCustomApplicationPage.aspx" />
      </CommandUIHandlers>
    </CommandUIExtension>
  </CustomAction>
</Elements>

This specifies that my Custom Action will appear on my custom list with TemplateType of 10005 (specified in the RegistrationId attribute) in the list view section.

I then used a Feature to depoy my Custom Action.

All my Custom Action does is to send the user to a custom page that is located in the Layouts folder:

/MyWeb/_layouts/CustomPages/MyCustomApplicationPage.aspx

I then created my custom aspx page. Below is the mark up for the page:

<%@ Assembly Name="MyCustomAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e246903334b3e97b" %>
<%@ Page Language="C#" AutoEventWireup="true" Inherits="MyCustomNamespace.MyCustomControl"
    Debug="true" %>

And finally, below is the code behind for the aspx page:

namespace MyCustomNamespace
{
    public class MyCustomControl: UserControl
    {    
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            // run some custom code
            // then redirect the user back to the original page
        }
    }
}

Using this way I was able to link some custom code that would execute in response to someone clicking my custom action.

For everything you need to know about customising the SharePoin Ribbon please go here to Chris O’Brien’s blog post.

After spending a lot of time investigating how to customise the Ribbon to meet the requirements I had I can safely say this is by far the best and most comprehensive blog post I found on the net.

As I said earlier there are other ways you can use to achieve the same objective. You can easily link a custom action to execute some javascript function. I guess one option would be to link it to a javascript function that then invoked some server side code. I havent tried this myself so I cannot say for sure if this approach would work.

If you had a similar issue to the one I had above, I would be interested in hearing what approach you used to resolve it (if different to the approach I used).

How To: Enable Incomming emails on a Custom SharePoint List

November 11, 2010 Leave a comment

First of all if this list is hosted in a Meeting Workspace Web then this will not work. Please refer to this post for complete details.

Briefly, this is what you need to do:

  • Create your custom SharePoint list
  • Attach an Event handler of type ‘EmailReceived’ to your list (once you do this the ‘Incoming Email Settings’ option will appear in the List Settings section of the site)
  • Add some code to your event handler as per your requirements to process the email
  • Deploy your list the usual way and create an instance of it (could be done as part of the deployment or via the UI)

In the example below I am picking up the subject of the email, creating a new list item where I set the title field value to match the subject. This is a very simple example but you can do a whole lot of stuff in this event handler such as processing attachments e.t.c.

public override void EmailReceived(SPList list, SPEmailMessage emailMessage, String receiverData)
{
    SPListItem newItem = list.Items.Add();
    newItem["Title"] = emailMessage.Headers["subject"]
    newItem.Update();
}

For complete details on how to configure your environment to facilitate processing of incoming emails please click here or here. There is also a very useful technet video on the subject here.

Enable Incoming emails on a Custom SharePoint List

November 11, 2010 12 comments

We had a requirement recently whereby we needed to create a custom SharePoint list that would accept incoming emails. This post is going to be very long so bear with me …

Initially, I was very optimisitic that all I needed to do was to setup incoming notifications via Central Administration and then turn on Incoming Email notifications on the list itself and it should all fall into place.

How wrong I was!

Setting up the Development Enviornment

The first thing you have to do is to setup your development enviornment so that you can send emails and your SharePoint list can recieve them. This turned out to be a massive task. I spent hours searching through blogs, forums and various sites to try and setup the infrastructure on my dev (Hyper-v VM based) enviornment but I just could not get it to work. Eventually I stubmled upon this post from Marc Charmois that explained in detail how to get the whole thing to work on your Dev enriornment:

Enabling Incoming-emails on the SharePoint List. The Problem:

Ok, so I created a custom SharePoint List went to List Settings and looked for the ‘In-coming email settings’ link under the ‘Communication’ settings and found it to be non-existent. Googling on this brought all sorts of theories, hearsay and rumours to light. Some thought that this option was only available on x,y or z type of lists then there were others that thought it was only available on a,b,c or d type of lists but one thing was for sure no one seemed to know for a fact what was actually going on. As I was looking at the object model I found a property on the SPList object called ‘CanReceieveEmail’. I thought maybe this was the answer i.e. all I needed to do was to get my list and set this property to true and it will all work. However you cannot set this property you can only get its value. I believe this property is used by the SharePoint UI to decide whether or not to show the ‘In-coming Email Settings’ link in the list settings area.

So it was time to fire up Reflector to find a way to set this property maybe through reflection?

Looking at the property via reflection I found:

public bool get_CanReceiveEmail()
{
    if (!SPEmailHandler.HasHandler(this.BaseTemplate) && !this.HasExternalEmailHandler)
    {
        return false;
    }
    return !SPMeeting.IsMeetingWorkspaceWeb(this.ParentWeb);
}

And ..

public static bool HasHandler(SPListTemplateType templateType)
{
    if ((((templateType != SPListTemplateType.Announcements) && (templateType !=    SPListTemplateType.Events)) && ((templateType != SPListTemplateType.DocumentLibrary)  && (templateType != SPListTemplateType.PictureLibrary))) && ((templateType !=  SPListTemplateType.XMLForm) && (templateType != SPListTemplateType.DiscussionBoard)))
    {
        return (templateType == SPListTemplateType.Posts);
    }
    return true;
}

And finally ….

internal bool HasExternalEmailHandler
{
    get
    {
        bool flag = false;
        foreach (SPEventReceiverDefinition definition in this.EventReceivers)
        {
            if (definition.Type == SPEventReceiverType.EmailReceived)
            {
                flag = true;
            }
        }
        return flag;
    }
}

From this we can determine the following:

If the list, regardless of its type, appears in a meeting workspace web it will not be able to recieve in-coming emails.

The list either needs to have the BaseTemplate of one of the following:

  • Announcements
  • Events
  • DocumentLibrary
  • PictureLibrary
  • XMLForm
  • DiscussionBoard
  • Posts

or it needs to have an event handler of type ‘EmailReceived’ attached to it.

An important point to note here is that it mentions the base template which should not be mistaken for the BaseType. What this means is that you could create a custom list that inherits from the BaseType Document Library but that does not mean that it will have incoming emails enabled. Your list will need to have the same BaseTemplate as the out of the box lists mentioned above which is not really ideal.

Enabling Incoming-emails on the SharePoint List. The Solution:

So the only route left for me to take was to go the Event Handler path. I attached the Event Handler (and the incomming email settings link started to appear in the list settings area) then sent an email to my list and debugged my code with a break point on my event handler. However it just never seemed to get hit and neither were my emails appearing in the list itself.

The mistake I was making was to attach the w3wp process but this is not the process that processes the incoming emails. I dont want to go into this in detail but the incoming emails are processed by a SharePoint job that runs every minute therefore the process I needed to attach was the OWSTimer process. Once I attached this process it started to hit my break point however the emails were still not appearing in the list.

One thing to note here is that whenever you make any code changes to this event handler, after you deploy the dll’s to GAC, you need to ensure you restart the SharePoint Timer Job Service because it holds a cached version of the dll’s.

Finally, the reason the emails were not appearing in the list was because this needs to be done via the Event Handler. For the lists that are from one of the Templates I mentioned above SharePoint understands how to process and add the email messages however for your own custom list it is down to the Developer to write the code to do this processing. The event handler though provides you an object of type SPEmailMessage which has all the data you require. Below is an example of how it can be used to add the email subject to a simple custom list with only a title field:

public override void EmailReceived(SPList list, SPEmailMessage emailMessage, String receiverData)
{
    SPListItem newItem = list.Items.Add();
    newItem["Title"] = emailMessage.Headers["subject"]
    newItem.Update();
}

You can easily extend it to deal with attachments as well but that is for another day!

P.S Illustrations to be added soon….

.NET WebControl: TextBox with counter

April 3, 2009 Leave a comment

Came across a need for a TextBox control with a countdown counter. Since I couldnt find one that would fit my requirements I decided to write one up.

It is in a very basic format at the moment and there is quite a lot that can be done with it. Feel free to improve, enhance, extend it.

Here is a screen shot of what it looks like:

TextBox with a countdown counter.

It is a very handy control to have.  You can use it in all three of the TextBox mode’s i.e. SingleLine, MultiLine, Password.

You can get the control and source code from here:

http://textboxwithcounter.codeplex.com/

Below is an example of how you can use this WebControl:

protected void Page_Load(object sender, EventArgs e)
{
    TextBoxWithCounter tbwCounter =  
    new TextBoxWithCounter(200, 5, 25, TextBoxMode.MultiLine);
    this.Form.Controls.Add(tbWcounter);
}

Programmatically adding a Web Part to the Web Part Gallery.

July 6, 2008 5 comments

I came across a problem whereby I needed to add a Web Part to the Web Part Gallery. The Web Part had been deployed successfully but as of yet it did not appear in the Web Part Gallery SPList. This needed to be done programmatically by using the SharePoint object model.

How do we programmatically add a Web Part (that has been deployed) to the Web Part Gallery. Using the SharePoint UI this is done via the NewDwp.aspx page.

The problem is that the list you see on the NewDwp.aspx page is not an SPList! Which makes life a bit tough! The other problem is that the .dwp files displayed in there do not exist until you select them and then click “Populate” by which time they are already in the Web Part Gallery.

I believe the NewDwp.aspx page builds the list of Web Parts, available to be added to the Gallery, from the web.config safe control enteries. Once you click “Populate” the page dynamically builds the .dwp file and adds it to the Gallery.

To add the Web Part to the Gallery programmatically you have to do the same i.e.

  1. Create the .dwp xml file dynamically
  2. Add it to the Web Part Gallery SPList

Below is the code to achieve this:

 
private static void AddWebPartToGallery()
{
    using (SPSite site = new SPSite("http://yoursite.com"))
    {
        using (SPWeb web = site.OpenWeb())
        {
            CreateDwpFile();
            
FileInfo fInfo = new FileInfo("myFile.dwp");
            FileStream fStream = fInfo.Open(FileMode.Open, FileAccess.Read);    
            web.AllowUnsafeUpdates =
true;
            site.AllowUnsafeUpdates =
true;    
            SPList list = web.Lists["Web Part Gallery"];
            SPFolder root = list.RootFolder;
            SPFile spFile = root.Files.Add("ContentEditor.dwp", s);
            spFile.Update();
        }
    }
}

The CreateDwpFile() method dynamically creates the .dwp file. Then open the Web Part Gallery List and the newly created .dwp file and add it to the root folder of the list.