The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.
In this blog post I am showing how to create a custom RadScheduler control that can be used to insert/update and delete content items. Generally the implementation is related to Events provider and IEvent objects. All data for the items managed through this control is persisted by the default Events provider.
We need to implement several properties
- EventsSchedule_AppointmentDelete
- EventsSchedule_AppointmentInsert
- EventsSchedule_AppointmentUpdate- EventsSchedule_AppointmentCreated
EventsScheduleViewContainer
RadScheduler declaration and control template
- in the template I have RadAjaxManagerProxy and RadAjaxManager with Loading panel in the template(master page file).
<telerik:RadAjaxManagerProxy runat="server" ID="RadAjaxManagerProxy1"> |
<AjaxSettings> |
<telerik:AjaxSetting AjaxControlID="eventsSchedule"> |
<UpdatedControls> |
<telerik:AjaxUpdatedControl ControlID="eventsSchedule" LoadingPanelID="RadAjaxLoadingPanel1" /> |
</UpdatedControls> |
</telerik:AjaxSetting> |
</AjaxSettings> |
</telerik:RadAjaxManagerProxy> |
<telerik:RadScheduler ID="eventsSchedule" runat="server" Skin="WebBlue" Width="500" Height="500"> |
<AppointmentContextMenuSettings EnableDefault="true" /> |
<TimeSlotContextMenuSettings EnableDefault="true" /> |
<AppointmentTemplate> |
<asp:HyperLink id="eventDetailsLink" runat="server" /> |
</AppointmentTemplate> |
</telerik:RadScheduler> |
using System; |
using System.Web.UI.WebControls; |
using Telerik.Events; |
using Telerik.Events.WebControls; |
using System.Linq; |
using System.Collections.Generic; |
using Telerik.Web.UI; |
using Telerik.Cms.Web.UI; |
using System.ComponentModel; |
using System.Web.UI; |
using Telerik.Framework.Web; |
using Telerik.Cms.Engine; |
using Telerik; |
using System.Web; |
using Telerik.Web; |
using Telerik.Cms.Engine.WebControls; |
/// <summary> |
/// Summary description for MyEventsScheduleView |
/// </summary> |
public class EventsScheduleViewCustom : CompositeControl |
{ |
#region Properties |
[System.ComponentModel.Category("Data")] |
public string ProviderName |
{ |
get |
{ |
string obj = (string)this.ViewState["ProviderName"]; |
if (string.IsNullOrEmpty(obj)) |
return "Events"; |
return (string)obj; |
} |
set |
{ |
this.ViewState["ProviderName"] = value; |
} |
} |
[WebEditor("Telerik.FileManager.UrlWebEditor, Telerik.FileManager"), |
System.ComponentModel.Category("Appearance"), |
System.Web.UI.Themeable(false), |
DefaultValue("")] |
public virtual string LayoutTemplatePath |
{ |
get |
{ |
object obj = this.ViewState["EventsScheduleViewTemplatePath"]; |
if (obj == null) |
return "~/Sitefinity/ControlTemplates/Events/EventsScheduleView.ascx"; |
return (string)obj; |
} |
set |
{ |
this.ViewState["EventsScheduleViewTemplatePath"] = value; |
} |
} |
[Browsable(false), |
System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty), |
DefaultValue(typeof(ITemplate), ""), |
Description("Events Schedule View template"), |
TemplateContainer(typeof(EventsScheduleView)) |
] |
public virtual ITemplate LayoutTemplate |
{ |
get |
{ |
if (layoutTemplate == null) |
layoutTemplate = ControlUtils.GetTemplate<DefaultTemplate>(LayoutTemplatePath); |
return layoutTemplate; |
} |
set |
{ |
layoutTemplate = value; |
} |
} |
[WebEditor("Telerik.Cms.Web.UI.UrlEditorWrapper, Telerik.Cms"), |
Category("Behavior")] |
public virtual string SingleEventUrl |
{ |
get |
{ |
object obj = ViewState["SingleEventUrl"]; |
if (obj != null) |
return (string)obj; |
return String.Empty; |
} |
set |
{ |
ViewState["SingleEventUrl"] = value; |
} |
} |
#endregion |
#region Overriden Methods |
protected override void OnInit(EventArgs e) |
{ |
base.OnInit(e); |
if (base.Page != null) |
base.Page.RegisterRequiresControlState(this); |
if (String.IsNullOrEmpty(providerName)) |
providerName = EventsManager.DefaultContentProvider; |
if (!String.IsNullOrEmpty(providerName)) |
{ |
if (eventsManager == null || eventsManager.Provider.Name != providerName) |
eventsManager = new EventsManager(providerName); |
} |
} |
/// <summary> |
/// Gets the HTML tag for the ListDisplay. |
/// </summary> |
protected override HtmlTextWriterTag TagKey |
{ |
get |
{ |
return HtmlTextWriterTag.Div; |
} |
} |
protected override void LoadControlState(object savedState) |
{ |
if (savedState != null) |
{ |
object[] state = (object[])savedState; |
providerName = (string)state[0]; |
from = (DateTime)state[1]; |
to = (DateTime)state[2]; |
} |
} |
protected override object SaveControlState() |
{ |
return new object[] { |
providerName, |
from, |
to |
}; |
} |
protected override void OnPreRender(EventArgs e) |
{ |
base.OnPreRender(e); |
} |
protected override void CreateChildControls() |
{ |
Controls.Clear(); |
if (Page == null || DesignMode) |
{ |
Label noDesignModeLabel = new Label(); |
noDesignModeLabel.Text = "The control cannot be previewed in design mode."; |
Controls.Add(noDesignModeLabel); |
} |
else |
{ |
container = new EventsScheduleViewContainer(this); |
LayoutTemplate.InstantiateIn(container); |
ObjectDataSource dataSource = new ObjectDataSource(); |
dataSource.ID = "EventsDataSource"; |
dataSource.TypeName = "Telerik.Events.EventsManager"; |
dataSource.SelectMethod = "GetEvents"; |
dataSource.SelectParameters.Add("from", TypeCode.DateTime, from.ToString()); |
dataSource.SelectParameters.Add("to", TypeCode.DateTime, to.ToString()); |
dataSource.SelectParameters.Add("sortExpression", String.Empty); |
dataSource.SelectParameters.Add("status", ContentStatus.Published.ToString()); |
dataSource.ObjectCreating += new ObjectDataSourceObjectEventHandler(dataSource_ObjectCreating); |
dataSource.Selecting += new ObjectDataSourceSelectingEventHandler(dataSource_Selecting); |
Controls.Add(dataSource); |
container.EventsSchedule.DataSourceID = dataSource.ID; |
container.EventsSchedule.DataKeyField = "ID"; |
container.EventsSchedule.DataSubjectField = "EventTitle"; |
container.EventsSchedule.DataStartField = "Start"; |
container.EventsSchedule.DataEndField = "End"; |
// allow delete, insert and edit. |
container.EventsSchedule.AllowDelete = true; |
container.EventsSchedule.AllowInsert = true; |
container.EventsSchedule.AllowEdit = true; |
container.EventsSchedule.AppointmentUpdate += new AppointmentUpdateEventHandler(EventsSchedule_AppointmentUpdate); |
container.EventsSchedule.AppointmentInsert += new AppointmentInsertEventHandler(EventsSchedule_AppointmentInsert); |
container.EventsSchedule.AppointmentDelete += new AppointmentDeleteEventHandler(EventsSchedule_AppointmentDelete); |
container.EventsSchedule.AppointmentCreated += new AppointmentCreatedEventHandler(EventsSchedule_AppointmentCreated); |
Controls.Add(container); |
} |
} |
void EventsSchedule_AppointmentDelete(object sender, SchedulerCancelEventArgs e) |
{ |
var eventsManager = new EventsManager("Events"); |
IEvent deleteEvent = eventsManager.GetEvent(new Guid(e.Appointment.ID.ToString())); |
eventsManager.DeleteEvent(deleteEvent.ID, true); |
} |
void EventsSchedule_AppointmentInsert(object sender, SchedulerCancelEventArgs e) |
{ |
var eventsManager = new EventsManager("Events"); |
IContent newEvent = eventsManager.Content.CreateContent("text/html"); |
newEvent.Content = e.Appointment.Subject; |
newEvent.SetMetaData("Title", e.Appointment.Subject); |
newEvent.SetMetaData("Event_Start", e.Appointment.Start); |
newEvent.SetMetaData("Event_End", e.Appointment.End); |
eventsManager.Content.SaveContent(newEvent, ContentStatus.Published); |
} |
void EventsSchedule_AppointmentUpdate(object sender, AppointmentUpdateEventArgs e) |
{ |
var eventsManager = new EventsManager("Events"); |
IEvent updateEvent = eventsManager.GetEvent(new Guid(e.Appointment.ID.ToString())); |
updateEvent.ContentItem.SetMetaData("Title", e.ModifiedAppointment.Subject); |
updateEvent.ContentItem.SetMetaData("Event_Start", e.Appointment.Start); |
updateEvent.ContentItem.SetMetaData("Event_End", e.Appointment.End); |
eventsManager.Content.SaveContent(updateEvent.ContentItem, ContentStatus.Published); |
} |
#endregion |
#region Helper methods |
// getting the item url that will be used in EventsView control |
protected virtual string GetItemUrl(IContent contentItem, string singleItemUrl) |
{ |
string sep = String.Empty; |
string ret = String.Empty; |
string url = singleItemUrl; |
if (String.IsNullOrEmpty(url) && CmsContext.CurrentUrl != null) |
{ |
url = CmsContext.CurrentUrl.Path; |
} |
else |
{ |
sep = "&"; |
ret = String.IsNullOrEmpty(Context.Request.QueryString["ReturnURL"]) ? String.Concat("ReturnURL=", Context.Server.UrlEncode(Context.Request.RawUrl)) : String.Concat("ReturnURL=", Context.Server.UrlEncode(Context.Request.QueryString["ReturnURL"])); |
} |
if (String.IsNullOrEmpty(contentItem.Url)) |
{ |
if (url != null) |
{ |
int idx = url.IndexOf('?'); |
if (idx != -1) |
url = url.Substring(0, idx); |
} |
url = String.Concat(url, "?", |
ContentManager.ContentProviderKey, "=", contentItem.ProviderName, "&", |
ContentManager.ContentItemKey, "=", contentItem.ID, sep, ret); |
} |
else |
{ |
string itemUrl = String.Concat(contentItem.Url, eventsManager.Provider.ContentExtension); |
if (eventsManager.Provider.UrlFormatQueryStringIndex != -1) |
{ |
itemUrl += "?" + ContentUrlRewriterService.FormatURL(contentItem, eventsManager.Provider |
, ContentUrlRewriterService.FormatOptions.QueryString); |
} |
else if (sep.Length > 0) |
{ |
sep = "?"; |
} |
if (!itemUrl.StartsWith("~")) |
{ |
if (url != null) |
{ |
int idx = url.LastIndexOf('.'); |
if (idx != -1) |
{ |
url = url.Substring(0, idx); |
} |
else |
{ |
idx = url.IndexOf('?'); |
if (idx != -1) |
url = url.Substring(0, idx); |
} |
} |
itemUrl = String.Concat(VirtualPathUtility.RemoveTrailingSlash(url), itemUrl); |
} |
url = String.Concat(itemUrl, sep, ret); |
} |
IUrlService svc = UrlServices.GetLanguageService(); |
if (svc != null) |
return svc.ResolveLanguageUrl(url); |
return url; |
} |
#endregion |
#region Event handlers |
private void dataSource_Selecting(object sender, EventArgs e) |
{ |
((ObjectDataSourceView)sender).SelectParameters["from"] = new Parameter("from", TypeCode.DateTime, from.ToString()); |
((ObjectDataSourceView)sender).SelectParameters["to"] = new Parameter("to", TypeCode.DateTime, to.ToString()); |
} |
private void dataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e) |
{ |
e.ObjectInstance = eventsManager; |
} |
private void EventsSchedule_AppointmentCreated(object sender, AppointmentCreatedEventArgs e) |
{ |
var eventsManager = new EventsManager("Events"); |
IEvent _event = eventsManager.GetEvent(new Guid(e.Appointment.ID.ToString())); |
if (_event != null) |
{ |
HyperLink eventDetailsLink = (HyperLink)e.Container.FindControl("eventDetailsLink"); |
if (eventDetailsLink != null) |
{ |
eventDetailsLink.Text = e.Appointment.Subject; |
eventDetailsLink.ToolTip = _event.ContentItem.Content.ToString(); |
eventDetailsLink.NavigateUrl = GetItemUrl(_event.ContentItem, SingleEventUrl); |
} |
} |
} |
#endregion |
#region Private fields |
private string providerName; |
private EventsManager eventsManager; |
private ITemplate layoutTemplate; |
private EventsScheduleViewContainer container; |
private DateTime from = DateTime.MinValue; |
private DateTime to = DateTime.MaxValue; |
#endregion |
#region Templates |
private class DefaultTemplate : ITemplate |
{ |
public void InstantiateIn(Control container) |
{ |
} |
} |
#endregion |
#region Containers |
private class EventsScheduleViewContainer : GenericContainer<EventsScheduleViewCustom> |
{ |
public EventsScheduleViewContainer(EventsScheduleViewCustom owner) |
: base(owner) |
{ |
} |
public RadScheduler EventsSchedule |
{ |
get |
{ |
if (eventsSchedule == null) |
eventsSchedule = (RadScheduler)FindRequiredControl<Control>("eventsSchedule"); |
return eventsSchedule; |
} |
} |
private RadScheduler eventsSchedule; |
} |
#endregion |
} |
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.