This example illustrates how you can bind the XtraScheduler to a collection of custom business objects. To accomplish this task, you should have two collections - one for appointments, another for resources. The appointment collection should implement the IBindingList interface. You can implement this interface manually in your custom collection, but we recommend you use the System.ComponentModel.BindingList<T> collection.
Additionally, your business object should have properties suitable for mapping to the corresponding properties of XtraScheduler's appointments and resources.
Question Comments
Added By: Pete R at: 4/23/2013 5:16:30 PM
Hello,
This sample uses old technology and is needlessly confusing. It is not necessary to manually implement the IBindingList interface. One can use the BindingList<T> class along with a BindingSource. For example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraScheduler;
using System.Linq;
namespace CustomObjectsBinding {
public partial class Form1 : Form {
public static Random RandomInstance = new Random();
private BindingList<CustomResource> m_customResourceBindingList = new BindingList<CustomResource>();
private BindingSource m_customResourceBindingSource = new BindingSource();
private BindingList<CustomAppointment> m_customAppointmentBindingList = new BindingList<CustomAppointment>();
private BindingSource m_customAppointmentBindingSource = new BindingSource();
public Form1() {
InitializeComponent();
schedulerStorage1.Resources.ColorSaving = ColorSavingType.Color;
}
private void Form1_Load(object sender, EventArgs e) {
InitResources();
InitAppointments();
schedulerControl1.Start = DateTime.Now;
UpdateControls();
}
private void InitResources() {
ResourceMappingInfo mappings = this.schedulerStorage1.Resources.Mappings;
mappings.Id = "ResID";
mappings.Color = "ResColor";
mappings.Caption = "Name";
m_customResourceBindingList.Add(CreateCustomResource(1, "Max Fowler", Color.PowderBlue));
m_customResourceBindingList.Add(CreateCustomResource(2, "Nancy Drewmore", Color.PaleVioletRed));
m_customResourceBindingList.Add(CreateCustomResource(3, "Pak Jang", Color.PeachPuff));
m_customResourceBindingSource.DataSource = m_customResourceBindingList;
this.schedulerStorage1.Resources.DataSource = m_customResourceBindingSource;
}
private CustomResource CreateCustomResource(int res_id, string caption, Color ResColor) {
CustomResource cr = new CustomResource();
cr.ResID = res_id;
cr.Name = caption;
cr.ResColor = ResColor;
return cr;
}
private void InitAppointments() {
AppointmentMappingInfo mappings = this.schedulerStorage1.Appointments.Mappings;
mappings.Start = "StartTime";
mappings.End = "EndTime";
mappings.Subject = "Subject";
mappings.AllDay = "AllDay";
mappings.Description = "Description";
mappings.Label = "Label";
mappings.Location = "Location";
mappings.RecurrenceInfo = "RecurrenceInfo";
mappings.ReminderInfo = "ReminderInfo";
mappings.ResourceId = "OwnerId";
mappings.Status = "Status";
mappings.Type = "EventType";
List<CustomAppointment> appointmentList = new List<CustomAppointment>();
GenerateEvents(appointmentList);
m_customAppointmentBindingList = new BindingList<CustomAppointment>(appointmentList);
m_customAppointmentBindingSource.DataSource = m_customAppointmentBindingList;
this.schedulerStorage1.Appointments.DataSource = m_customAppointmentBindingSource;
}
private void GenerateEvents(List<CustomAppointment> eventList) {
int count = schedulerStorage1.Resources.Count;
for (int i = 0; i < count; i++) {
Resource resource = schedulerStorage1.Resources[i];
string subjPrefix = resource.Caption + "'s ";
eventList.Add(CreateEvent(subjPrefix + "meeting", resource.Id, 2, 5));
eventList.Add(CreateEvent(subjPrefix + "travel", resource.Id, 3, 6));
eventList.Add(CreateEvent(subjPrefix + "phone call", resource.Id, 0, 10));
}
}
private CustomAppointment CreateEvent(string subject, object resourceId, int status, int label) {
CustomAppointment apt = new CustomAppointment();
apt.Subject = subject;
apt.OwnerId = resourceId;
Random rnd = RandomInstance;
int rangeInMinutes = 60 * 24;
apt.StartTime = DateTime.Today + TimeSpan.FromMinutes(rnd.Next(0, rangeInMinutes));
apt.EndTime = apt.StartTime + TimeSpan.FromMinutes(rnd.Next(0, rangeInMinutes / 4));
apt.Status = status;
apt.Label = label;
return apt;
}
private void UpdateControls() {
this.radioGroup1.EditValue = (int)schedulerControl1.GroupType;
}
private void radioGroup1_SelectedIndexChanged(object sender, EventArgs e) {
schedulerControl1.GroupType = (SchedulerGroupType)radioGroup1.EditValue;
}
}
}
Then one can use LINQ to Objects and do things like:
List<CustomAppointment> travelList = m_customAppointmentBindingList.Where(x => x.Subject.Contains("travel")).ToList();
etc. Without the need to implement the binding interfaces, the CustomObjects.cs file can be reduced to:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Collections;
using System.Drawing;
namespace CustomObjectsBinding {
public class CustomAppointment
{
private DateTime m_Start;
private DateTime m_End;
private string m_Subject;
private int m_Status;
private string m_Description;
private long m_Label;
private string m_Location;
private bool m_Allday;
private int m_EventType;
private string m_RecurrenceInfo;
private string m_ReminderInfo;
private object m_OwnerId;
public DateTime StartTime { get { return m_Start; } set { m_Start = value; } }
public DateTime EndTime { get { return m_End; } set { m_End = value; } }
public string Subject { get { return m_Subject; } set { m_Subject = value; } }
public int Status { get { return m_Status; } set { m_Status = value; } }
public string Description { get { return m_Description; } set { m_Description = value; } }
public long Label { get { return m_Label; } set { m_Label = value; } }
public string Location { get { return m_Location; } set { m_Location = value; } }
public bool AllDay { get { return m_Allday; } set { m_Allday = value; } }
public int EventType { get { return m_EventType; } set { m_EventType = value; } }
public string RecurrenceInfo { get { return m_RecurrenceInfo; } set { m_RecurrenceInfo = value; } }
public string ReminderInfo { get { return m_ReminderInfo; } set { m_ReminderInfo = value; } }
public object OwnerId { get { return m_OwnerId; } set { m_OwnerId = value; } }
public CustomAppointment()
{
}
}
public class CustomResource {
private string m_name;
private int m_res_id;
private Color m_res_color;
public string Name { get { return m_name; } set { m_name = value; } }
public int ResID { get { return m_res_id; } set { m_res_id = value; } }
public Color ResColor { get { return m_res_color; } set { m_res_color = value; } }
public CustomResource()
{
}
}
}
Please verify.
Added By: Tejaswi Rana at: 10/24/2013 3:41:59 PMWhat is the bare minimum mapping details necessary to display an appointment? For example, I have an object that only has the properties StartTime, EndTime, Description & Type. I have not linked any resources to any of these objects. And I am using a bindingList<of thisClass>. This is in version 8.3. I don't see any output.
Added By: Tejaswi Rana at: 10/24/2013 6:56:08 PMI will answer the above myself: This works in version 8.3. Actually the comment above helped a lot :).
Also, there is no need to have resources if you're including them within something like "description" of the appointment itself.
You can have as many mappings as you want to send. The only thing to be careful about is if you have a mapping and don't send data or proper data type.
Can you add to this example to show how to add appointments after the initial load? I am using a custom dialog and adding my objects to my source binding list, but they do not appear until I completely reload my gantt chart.
Added By: Andrey (DevExpress Support) at: 9/2/2015 8:18:38 AMHello,
To process your recent post more efficiently, I created a separate ticket on your behalf: T285177: How to refresh the scheduler on adding an appointment in the E750 example. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.