1

Is there a way to get the text displayed for the "Recurrence" field on the View Item screen for an OOB "Event" list item through the object model? For example, I see:

"Every 1 month(s) on the first Tuesday"

Is there maybe a calculated field that I can reference using an SPListItem to get at this string (ensuring it's localized correctly)? For example:

lblRecurrence.Text = item["RecurrenceText"].ToString();

Response targeted for SP2007, but interested if this carries over to 2010? Or if there is a way to get at it in 2010 that wasn't there before?

3 Answers 3

3

So here is what I have come up with.

I created a simple console application to point at the "Event" list and loop through each of the SPListItems in it. For each SPListItem, I output the fields and values. I then looked through the document and I found nothing that resembled the "Recurrence Display Text". I also looked at the Schema.xml and confirmed there was nothing in there that looked similar to what I was looking for.

I started dissecting other pieces. Ultimately what I found where two controls:

Microsoft.SharePoint.WebControls.RecurrenceDataControl
Microsoft.SharePoint.WebControls.RecurrenceField

I opened these up with Reflector and analyzed the internals.

RecurrenceDataControl appears to be strictly for EDITING recurrence data. Nice because this saves me from having to write this UI myself in my custom form. I can just instantiate an instance of this control and pass it a reference to the "RecurrenceData" xml (and give it references to item/list/web context).

RecurrenceField can be used for either EDITING or DISPLAYING of recurrence data. This is controlled by the ControlMode proeprty. The difference between RecurrenceField and RecurrenceDataControl for EDITING seems to be that RecurrenceDataControl only handles the xml portion of the recurrence data (the "RecurrenceData" field in the SPListItem), whereas the RecurrenceField control appears facilitate the checkbox/toggling functionality (and corresponds to the "fRecurrence" SPListItem field).

Simplified: RecurrenceField uses RecurrenceDataControl.

For getting at the textual representation, then, I can use the RecurrenceField control. The problem is, I need just the text, no markup. I don't actually want to let this render down myself (ultimately I am returning this text through a service layer). I am accomplishing this by the following:

    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    HtmlTextWriter htw = new HtmlTextWriter(sw);

    RecurrenceField local = new RecurrenceField();
    local.ID = "testing1";
    local.ListId = List.ID;
    local.ItemId = Item.ID;
    local.FieldName = "fRecurrence";

    SPContext context = SPContext.GetContext(this.Context, Item.ID, List.ID, Web);
    local.ItemContext = context;
    //local.RenderContext = context;

    local.RenderControl(htw); //this is the KEY!

    htw.Flush();
    sw.Flush();
    Console.WriteLine(sb.ToString());
4
  • I forgot to mention, I tested the above with the English and Ukrainian language packs. The results I got were consistent with what was displaying in the Out of the Box (OOB) SharePoint DispForm.aspx.
    – Brian
    Commented Sep 14, 2010 at 16:23
  • Also, forgot to mention that this appears to apply to both 2007 and 2010 versions of the product as the controls/classes used here are available (and not marked for deprecation) in either.
    – Brian
    Commented Sep 14, 2010 at 16:24
  • I am having a similar requirement of needing to pull the display pattern for a recurring event. I have inherited a custom solution that sends and email once users create an event, to the existing notification I would like to add the pattern for recurring events. I am having trouble following your example, I am a newbie to sharepoint development. Thanks, Karen
    – user32715
    Commented Aug 21, 2014 at 22:12
  • Hi Karen. Apologies as I don't check back in here too often these days. I happened to maybe need this so I wen't searching for something I thought I had done around "friendly user display of recurrence items in SharePoint". As with many things in SharePoint, there are no public API's for getting at what you want/need, so you must get creative and try to "HACK" something together. This is a perfect example of that. All this is doing is using a SharePoint control and faking as if it were rendering on a web page.
    – Brian
    Commented Nov 10, 2014 at 16:35
0

Brian, thanks a lot! I've lost a week by exploring this topic (

I've just modified your code for event receivers...

string m_recurrenceText = null;

//Constructor
public MyEventReceiver()
{
    SPContext spContext = SPContext.Current;
    if (spContext != null)  //works for synchronous event receivers only
        LoadRecurrenceText(spContext.ListItem);
}

//Recurrence form field simulating for recurrence text renderring
protected void LoadRecurrenceText(SPListItem spListItem)
{
    try
    {
        RecurrenceField recurrenceField = new RecurrenceField();
        recurrenceField.ListId = spListItem.ParentList.ID;
        recurrenceField.ItemId = spListItem.ID;
        recurrenceField.FieldName = "fRecurrence";
//don't need this   recurrenceField.ItemContext = recurrenceField.RenderContext = SPContext.GetContext(HttpContext.Current, spListItem.ID, spListItem.ParentList.ID, spListItem.Web);
        recurrenceField.ControlMode = SPControlMode.Display;

        m_recurrenceText = recurrenceField.GetDesignTimeHtml();
    }

    catch (Exception) { ;}
}

The problem is: this works with two limitations only:
1) when HttpContext.Current is available - inside event receiver constructor for synchronous event receivers (like ItemAdding and ItemUpdating).
2) with value that already recorded (list item ID is available).

So if you want to send it in e-mail, you can do this in ItemUpdating event receiver only and with old value (that is recorded in ListItem), if it was modified in AfterProperties, you'll send the old value :).

0

I've discovered a solution for Event Receivers!

All that you need - is to create fake HttpContent. And you no longer need a constructor and class members, and now you can get recurrence text everywhere in any Event Receiver (synchronous and asynchronous).

Thanks for Ehi Kioya! https://ehikioya.com/creating-fake-spcontext/

Here is my final solution:

protected string GetRecurrenceText(SPListItem spListItem)
{
    try
    {
        //fake SP context creating
        if (HttpContext.Current == null)
        {
            HttpRequest httpRequest = new HttpRequest("", spListItem.Web.Url, "");
            HttpResponse httpResponse = new HttpResponse(TextWriter.Null);
            HttpContext.Current = new HttpContext(httpRequest, httpResponse);
        }
        if (HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
            HttpContext.Current.Items["HttpHandlerSPWeb"] = spListItem.Web;

        //field simulating
        RecurrenceField recurrenceField = new RecurrenceField();
        recurrenceField.ListId = spListItem.ParentList.ID;
        recurrenceField.ItemId = spListItem.ID;
        recurrenceField.FieldName = "fRecurrence";
        recurrenceField.ControlMode = SPControlMode.Display;

        //control rendering
        return recurrenceField.GetDesignTimeHtml();
    }

    catch (Exception) { ;}
    return null;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.