Sunday, June 14, 2015

Binding ScehduleView to Database part 3: Implement IAppointment

As we saw in the previous post, the best way is to implement the IAppointment interface without inheritance from Appointment class.

The whole code is available on GitHub, and below we will go over the code and explain every block.


1. Class:


public class AppointmentModel : BindableBase, IAppointment, IExtendedAppointment

Remarks:

The class must be derived from INotifyPropertyChanged, in order to update the UI when the properties are changing. BindableBase is an abstract class provided by Prism.Mvvm package,  which you can derive your view model classes that implements the INotifyPropertyChanged interface in a type-safe manner.

If you prefer another Mvvm framework, use their equivalent class. For example:  if you use MVVMLight, use ViewModelBase as base class instead of BindableBase, and for properties use ViewModelBase.Set method, instead of BindableBase.SetProperty.

The IExtendedAppointment interface extends the appointment with three properties: ImportanceCategory and TimeMarker.

2. Properties

[Key]
public int Id { get; set; }

#region properties

private string subject, body;
private DateTime start, end;
private bool isAllDayEvent;
private Importance importance;

public string Subject
{
    get { return subject; }
    set { SetProperty(ref subject, value); }
}

public string Body
{
    get { return body; }
    set { SetProperty(ref body, value); }
}

public DateTime Start
{
    get { return start; }
    set { SetProperty(ref start, value); }
}

public DateTime End
{
    get { return end; }
    set { SetProperty(ref end, value); }
}

public bool IsAllDayEvent
{
    get { return isAllDayEvent; }
    set { SetProperty(ref isAllDayEvent, value); }
}

public Importance Importance
{
    get { return importance; }
    set { SetProperty(ref importance, value); }
}

#endregion // IAppointment

#region Unused properties

IRecurrenceRule IAppointment.RecurrenceRule
{
    get;
    set;
}

IList IAppointment.Resources
{
    get { return new List<Resource>(); }
}

[NotMapped]
public TimeZoneInfo TimeZone
{
    get;
    set;
}

ICategory IExtendedAppointment.Category
{
    get;
    set;
}

ITimeMarker IExtendedAppointment.TimeMarker
{
    get;
    set;
}

#endregion // Unused properties

Remarks:

The TimeZone property must be ignored [not mapped to database]
RecurrenceRule and Resources properties We implement explicitly. they doesn't doing nothing yet, and we will discuss about them later in coming posts.

Right now, from IExtendedAppointment, only Importance is mapped to the database, because it is a plan enum value. in coming posts we will discuss the other properties.


3. Event handlers

The IAppointment interface defines a one event:

public event EventHandler RecurrenceRuleChanged;

public void OnRecurrenceRuleChanged(EventArgs args)
{
    EventHandler recurrenceRuleChanged = this.RecurrenceRuleChanged;

    if (recurrenceRuleChanged != null)
    {
        recurrenceRuleChanged(this, args);
    }
}


4. ICopyable

We need also implement ICopyable<T> interface.

public IAppointment Copy()
{
    AppointmentModel appointment = new AppointmentModel();
    appointment.CopyFrom(this);
    return appointment;
}

public void CopyFrom(IAppointment other)
{
    AppointmentModel appointment = other as AppointmentModel;

    if (appointment == null)
        return;

    this.Id = appointment.Id;
    this.Subject = appointment.Subject;
    this.Body = appointment.Body;
    this.Start = appointment.Start;
    this.End = appointment.End;
    this.IsAllDayEvent = this.IsAllDayEvent;
    this.Importance = appointment.Importance;
}

Remarks:

This interface is very important because it's used by ScheduleView conrol. When the user opens some appointment for edit, the ScheduleView  doesn't opens the original appointment, but creates a copy of the appointment using IAppointment.Copy method.
After editing, when the user clicks OK, the ScheduleView control copies back all changes to the original appointment by using IAppointment.CopyFrom method.


5. IEquatable

The IAppointment interface is derived from IEquatable<T> interface, where T is IAppointment. So we need implement the Equals method:

public bool Equals(IAppointment other)
{
    AppointmentModel otherApp = other as AppointmentModel;

    return otherApp != null
        && otherApp.Id == this.Id;
}


6. IEditableObject

The IAppointment interface is derived also from IEditableObject interface. We can implement it Explicitly, because we will not use it.

void IEditableObject.BeginEdit()
{
}

void IEditableObject.CancelEdit()
{
}

void IEditableObject.EndEdit()
{
}

7. Conclusion

We saw the implementation of IAppointment interface. We doesn't need to do any change in the database schema, but delete the OnModelCreating from SchedulingDbContext class.

you can see all the changes on my GitHub repo, see the link above.

Now, we can run the application, and we have same functionality like using the previous QuickStart post.

No comments:

Post a Comment