Sunday, June 14, 2015

Binding ScheduleView to Database part 4: Categories

Let's see how to work with categories and database.

The source code for this post, is available on GitHub.


1. CategoryModel class

First, we need define a class, which it is derived from ICategory interface.

public class CategoryModel : BindableBase, ICategory

I use the Model suffix, to avoid confusing with Telerik's Category class.
Usually, we want also give to user the ability of Edit the categories, therefore our class must be derived from INotifyPropertyChanged or BidnableBase [ViewModelBase if you use MVVMLight].

2. CategoryModel properties


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

private string categoryName, categoryColorString;

public string CategoryName
{
    get { return this.categoryName; }
    set
    {
        SetProperty(ref categoryName, value);
        OnPropertyChanged(() => this.DisplayName);
    }
}

public string CategoryColorString
{
    get { return categoryColorString; }
    set
    {
        if (SetProperty(ref categoryColorString, value))
        {
            base.OnPropertyChanged(() => CategoryBrush);
            base.OnPropertyChanged(() => CategoryColor);
        }
    }
}

// Relationships
public virtual ICollection<AppointmentModel> Appointments { get; set; }

[NotMapped]
public string DisplayName
{
    get { return this.CategoryName; }
    set { this.CategoryName = value; }
}

#region color properties

public Color CategoryColor
{
    get
    {
        Color color = Helpers.ColorHelper.ParseOrDefault(categoryColorString, Colors.White);
        return color;
    }
    set { CategoryColorString = value.ToString(); }
}

public Brush CategoryBrush
{
    get { return new SolidColorBrush(CategoryColor); }
}

#endregion // color properties

Remarks:


The CategotyModel provides two functions: CategoryName and CategoryColor.
The ICategory interface defines also a DisplayName property, but for simplification we implement it as a wrapper for DisplayName property.

The coloring functionality has two formats: Since the UI show the color using CategoryColor and CategoryBrush properties, the database store the color as string, using CategoryColorString property.

The ColorHelper is an helper class that convert string to Color. You can see it in the GitHub repository.


3. Relationship with AppointmentModel class

Now, we need associate the CategoryModel to AppointmentModel. Let's edit the AppointmentModel class:

public int? CategoryId { get; set; }

private CategoryModel category;

public virtual CategoryModel Category
{
    get { return this.category; }
    set { SetProperty(ref category, value); }
}

ICategory IExtendedAppointment.Category
{
    get { return this.Category; }
    set { this.Category = value as CategoryModel; }
}

4. The Context

Add this line to SchdulingDbContext class:

public DbSet<CategoryModel> Categories { get; set; }


5. View and ViewModel

The MainViewModel load the categories from the database into Local, and exposes the Local collection as a property.

public MainViewModel()
{
    ...
    context.Categories.Load();
}

public ObservableCollection<CategoryModel> Categories
{
    get { return context.Categories.Local; }
}


In the View side, the ScheduleView control consumes the Categories property by his CategoriesSource property.


6. Conclusion


In this post we saw how implement the ICategory class, how to define the relationships between CategoryModel and AppointmentModel, and how to define the View and ViewModel.

After to do all these changes, you need upload the changes to your database. If you work with Code first strategy, run add-migration categories command, and then update-database command.

If you want initialize the categories collection, you can define your categories in Seed method of the Configuration class.
protected override void Seed(SchedulingDbContext context)
{
    context.Categories.AddOrUpdate(
        category => category.DisplayName,
        new CategoryModel { DisplayName = "Red category",CategoryColor = System.Windows.Media.Colors.Red},
        new CategoryModel { DisplayName = "Yellow category", CategoryColor = System.Windows.Media.Colors.Yellow },
        new CategoryModel { DisplayName = "Green category",CategoryColor = System.Windows.Media.Colors.Green}
    );
}

No comments:

Post a Comment