Sunday, February 12, 2012

Entity Framework Code First - Relationship between Entities II

This is part of the series of discussions about entity framework. In the last post, we touched the basics about relationship between entities. We discussed how the relational database concepts of different relationship types can be mapped to object oriented entities. We are progressively working on an Institute scenario discussing the various entity framework features.

In this post we will be adding on to the previous post by discussing the relationship between entities further. We will discuss how we can define one-to-many relationships. In the previous post we defined a relationship between Departments and Students entities. This relationship was defined such that a student might not belong to a department. If we look at the database table created, we see that there is a foreign key added in the Students table. It is allowing null values so a student can exist without belonging to any department.


In order to change the relationship to one-to-many, we need to specify it when the model is being built. We can do it by overriding OnModelCreating method of InstituteEntities (DbContext). Here we are specifying that it is mandatory for a student to belong to a department. Entity framework would not allow a student to be saved to the database without belonging to a department.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Student>().HasRequired(s => s.StudentDepartment);
}
This would result in generating the Students table as follows:


So the similar Id has been generated to hold foreign key for department but it is now specified as not null which changes the relationship to one-to-many from previous zero-to-many relationship. Basically EF Code First uses conventions for keys, either primary or foreign keys. Just adding a non-nullable primitive key for holding Department table's foreign key would update the table definition to have a non-nullable foreign key. If we keep the name as DepartmentId then based on convention based approach, the run-time would realize that this is to hold foreign key of Department and would make it non-nullable. Let us update Student's entity as follows:
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int GradePointAverage { get; set; }
        public bool IsOutStanding { get; set; }
        
        //Foreign key of Department
        public int DepartmentId { get; set; }

        public virtual ICollection<Course> StudentCourses { get; set; }
        public virtual Vehicle VehicleDetails { get; set; }
        public virtual Department StudentDepartment { get; set; }
    }
}
Just updating the above code would result in the updated Student's table in database as follows:


Please note that the name of foreign key is updated to be DepartmentId. It has also been updated as non-null. This would stop us from adding student without specifying department information. If we had needed the foreign key to be picked up based on convention but we still needed to keep the relationship as zero-to-many then we could just use a nullable type and framework would take care of that. Let's update DepartmentId as nullable int [int?] in Student table as follows:
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int GradePointAverage { get; set; }
        public bool IsOutStanding { get; set; }
        
        //Foreign key of Department
        public int? DepartmentId { get; set; }

        public virtual ICollection<Course> StudentCourses { get; set; }
        public virtual Vehicle VehicleDetails { get; set; }
        public virtual Department StudentDepartment { get; set; }
    }
}
This would result in the following Student's table in the database.


If we had used a name for Department's Id which is not based on convention then the framework obviously would not recognize the significance and would treat that field as just entity's property and would just create a column for the field in the database table. Let us update DepartmentId as DepartmentInfoId.
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int GradePointAverage { get; set; }
        public bool IsOutStanding { get; set; }
        
        //Foreign key of Department
        public int DepartmentInfoId { get; set; }

        public virtual ICollection<Course> StudentCourses { get; set; }
        public virtual Vehicle VehicleDetails { get; set; }
        public virtual Department StudentDepartment { get; set; }
    }
}
Now run the application. You can notice that the Student's table is created as follows:


Since the new key is not based on EF convention, the framework has not recognized it. In order to help the framework, we can specify this in OnModelCreating method of the DbContext as follows:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Student>().HasRequired(s => s.StudentDepartment)
                                  .WithMany(d => d.Students)
                                  .HasForeignKey(s => s.DepartmentInfoId);
}
Now the framework would realize that the DepartmentInfoId should be used to define foreign key relationship between Student and Department.


If we had needed a zero-to-many relationship, we would need to update DepartmentInfoId to allow null values.
//Foreign key of Department
public int? DepartmentInfoId { get; set; }
We also need to update OnModelCreating method in InstituteEntities as follows:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Student>().HasOptional(s => s.StudentDepartment)
                                  .WithMany(d => d.Students)
                                  .HasForeignKey(s => s.DepartmentInfoId);
}
The framework would still use DepartmentInfoId as Foreign key for Department table in Student table. It would just allow null for this allowing zero-to-many relationship.


Please remember that this would only be possible if we define DepartmentInfoId as nullable [int?]. If we just change it as follows then model validation would fail. Let us do that and change Student POCO as follows:
//Foreign key of Department
public int DepartmentInfoId { get; set; }
Now we run the application and see it crashing.


Download Code

Saturday, February 11, 2012

Entity Framework Code First - Relationship between Entities

This is the second post of our discussion about Entity Framework Code First. In this post we will be discussing how we can create relationship between two entities. Keeping to the code first ideology, code first entities would still be based on simple POCO classes. The relationship between entities are used by entity framework libraries to build the model and hence generate database if required.

As an example, we would be developing on top of our previous example. We have simply discussed how to create a simple application with Entity Framework Code First with one simple entity. Let's now expand this example by introducing courses in our institute. Students are assigned to these courses. Any number of students can be assigned to a course. These courses are offered at different campuses of the institute. The locations have physical presence and have a specific name. Since institute's parking space is limited so each student is allowed to register one vehicle. Each student belongs to a certain department.

Based on the above requirements, we can create following entities in our system.

  1. Student
  2. Vehicle
  3. Course
  4. CourseLocation
  5. Department

These are not stand alone entities but the requirements suggest that there are relationships between these entities.

  1. One-to-One: Since a Student is allowed to register only one vehicle, there is one-to-one relationship between the two.
  2. One-to-Many: A Department can enroll any number of students but a student only belongs to a single department. In this post, we will keep it simple by defining a zero-to-many relationship but we will see how we can fix it in the next post.
  3. Many-to-Many: Any number of students can be enrolled in a course. Similarly, a student can be enrolled in multiple courses. Likewise, a course can be offered at multiple locations and a location can host multiple courses.

Entities

Now let us define our entities. You can see that these are POCO based. They would definitely be backed by database objects when the application is running. But for a simple example, like this, we don't need to worry about that. And this is why Code First is great.

Student

namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int GradePointAverage { get; set; }
        public bool IsOutStanding { get; set; }

        public virtual ICollection<Course> StudentCourses { get; set; }
        public virtual Vehicle VehicleDetails { get; set; }
        public virtual Department StudentDepartment { get; set; }
    }
}

Vehicle

namespace EFCodeFirstDatabaseCreation.Entities
{
    class Vehicle
    {
        public int VehicleId { get; set; }
        public string Year { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }
}
Course
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Course
    {
        public int CourseId { get; set; }
        public string CourseName { get; set; }
        public ICollection<Student> CourseStudents { get; set; }
        public virtual ICollection<CourseLocation> CourseOfferedAt { get; set; }
    }
}
Department
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;

    class Department
    {
        public int DepartmentId { get; set; }
        public string DepartmentName { get; set; }
        public virtual ICollection<Student> Students { get; set; }
    }
}
CourseLocation
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    class CourseLocation
    {
        public int CourseLocationId { get; set; }
        public string LocationName { get; set; }
        public virtual LocationAddress Address { get; set; }
        public virtual ICollection<Course> CoursesOffered { get; set; }
    }

    [ComplexType]
    class LocationAddress
    {
        public string StreetAddress { get; set; }
        public string Apartment { get; set; }
        public string City { get; set; }
        public string StateProvince { get; set; }
        public string ZipCode { get; set; }
    }
}

Defining InstituteEntities [DbContext]

Now we need to define the DbContext to query these entities from the database. As you can see we don't need to add all the entities details in the DbContext. We only need to add those entities which are to be accessed directly using the DbContext instance. The other entities which have a relationship with these entities would still have a corresponding table in the database. It is just that they would be accessed to their corresponding relationship tables starting from the DbContext type.

namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Data.Entity;

    class InstituteEntities : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Course> Courses { get; set; }
        public DbSet<Department> Departments { get; set; }       
    }
}

Initializing Entities with Data

Let us initialize these entities with some data. Remember that this would result in actual data inserted in the tables mapped to these entities by Entity Framework.

namespace EFCodeFirstDatabaseCreation
{
    using EFCodeFirstDatabaseCreation.Entities;
    using System.Data.Entity;
    using System.Collections.Generic;

    class InstituteDatabaseInitializer : DropCreateDatabaseAlways<InstituteEntities>
    {        
        protected override void Seed(InstituteEntities context)
        {

            Student student1 = new Student()
            {
                FirstName = "Muhammad",
                LastName = "Siddiqi",
                IsOutStanding = true,
                GradePointAverage = 3
            };

            Vehicle vehicle = new Vehicle() { VehicleId = 1, Make = "Bugatti", Model = "", Year = "2012" };
            
            Department department1 = 
                new Department() { DepartmentId = 1, DepartmentName = "Computer Systems Engineering", Students = new List<Student>() };
            Department department2 = 
                new Department() { DepartmentId = 2, DepartmentName = "Electrical Engineering", Students = new List<Student>() };

            Student student2 = new Student()
            {
                FirstName = "Chattan",
                LastName = "Shah",
                IsOutStanding = true,
                GradePointAverage = 4, 
                VehicleDetails = vehicle
            };

            Student student3 = new Student()
            {
                FirstName = "Imran",
                LastName = "Ashraf",
                IsOutStanding = true,
                GradePointAverage = 4
            };

            Student student4 = new Student()
            {
                FirstName = "Jawad",
                LastName = "Qureshi",
                IsOutStanding = true,
                GradePointAverage = 4
            };

            CourseLocation courseLocation1 =
                new CourseLocation()
                    {
                        LocationName = "Karachi Campus",
                        Address = new LocationAddress() 
                                        {
                                            StreetAddress = "XYZ I.I. Chundrigar Road",
                                            City = "Karachi",
                                            StateProvince = "Sindh",
                                            ZipCode = "YYYYY"
                                        }
                    };

            CourseLocation courseLocation2 =
                new CourseLocation()
                {
                    LocationName = "Manhattan Campus",
                    Address = new LocationAddress()
                    {
                        StreetAddress = "6th Street",
                        City = "New York City",
                        StateProvince = "New York",
                        ZipCode = "ZZZZZ"
                    }
                };

            Course course1 = new Course()
                                    {
                                        CourseName = "Engineering Mechanics",
                                        CourseStudents = new List<Student> { student1, student2 },
                                        CourseOfferedAt = new List<CourseLocation> {courseLocation1, courseLocation2 }
                                    };


            Course course2 = new Course()
                                    {
                                        CourseName = "Fault Tolerence & Reliable System Design",
                                        CourseStudents = new List<Student> { student3, student4 },
                                        CourseOfferedAt = new List<CourseLocation>{courseLocation1}
                                    };

            Student student5 = new Student()
                                    {
                                        FirstName = "Ali",
                                        LastName = "Khan",
                                        GradePointAverage = 3,
                                        IsOutStanding = true
                                    };

            course1.CourseStudents.Add(student5);
            
            department1.Students.Add(student1);
            department1.Students.Add(student2);
            department1.Students.Add(student3);

            department2.Students.Add(student4);
            department2.Students.Add(student5);

            context.Courses.Add(course1);
            context.Courses.Add(course2);
            
            context.Departments.Add(department1);
            context.Departments.Add(department2);

            base.Seed(context);
        }
    }
}

Test Code:

Now let us write some test code to see if the entities are generated as expected. The code below would also test if the data has been inserted in those entities. Here we are setting database initializer for InstituteEntities. Then we are just writing the data to the console testing if the entities are initialized properly.

namespace EFCodeFirstDatabaseCreation
{
    using System.Linq;
    using EFCodeFirstDatabaseCreation.Entities;
    using System.Data.Entity;
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            //Initialize Database entities
            Database.SetInitializer<InstituteEntities>(new InstituteDatabaseInitializer());

            InstituteEntities instituteEntites = new InstituteEntities();
           
            foreach (var course in instituteEntites.Courses
                                        .Include("CourseStudents")
                                        .Include("CourseStudents.VehicleDetails")
                                        .Include("CourseStudents.StudentDepartment")
                                        .Include("CourseOfferedAt"))
            {
                string location = course.CourseOfferedAt == null ? string.Empty :
                    string.Join(", ", course.CourseOfferedAt.Select(l => l.LocationName).ToArray<string>());
                
                Console.WriteLine("***************************");
                Console.WriteLine("Course : {0}, Offered At: {1}", course.CourseName, location);

                foreach (var student in course.CourseStudents)
                {
                    Console.WriteLine(
                                string.Format("Student : {0} {1}, GPA : {2}",
                                               student.FirstName,
                                               student.LastName,
                                               student.GradePointAverage));

                    Console.WriteLine("   Department : {0}", student.StudentDepartment.DepartmentName);

                    if (student.VehicleDetails != null)
                    {
                        Console.WriteLine("   Vehicle: {0} {1} {2}",
                            student.VehicleDetails.Year, student.VehicleDetails.Make, student.VehicleDetails.Model);
                    }
                }
                
                Console.WriteLine("***************************");
            }

            Console.ReadLine();
        }
    }
}

Database Relationship:

You might be wondering how these relationships are created in the database.

One-to-One & One-to-Many:

These types of relationship result in adding the foreign key on one of these entities. In our case, the relationship between Vehicle and Student is one-to-one. A student is supposed to register only one vehicle in the system. On the other hand, the relationship between Department and Student is One-to-Many as a department could have more than student.

Many-to-Many

This is similar to generating Database from and Entity Relationship Diagram. This results in adding a relationship table in the Database. In our case the relationship between Student & Courses is many-to-many. This would result in generating a new table in database containing primary keys of both the entities. For our case, the name of this table is CourseStudents. Similarly, a course can be offered at multiple locations i.e. the relationship between Course and CourseLocation is also many-to-many. This results in creating CourseLocationCourses table in Database.

Complex Type

A complex type is represented in the database by adding all properties of complex type to the entity itself. By default, the names of these properties are preceded by the name of variant used for ComplexType instance in the entity.

Output:

When we run the project, it runs in the following output.

Download Code:

Thursday, January 19, 2012

Entity Framework 4.2 Code First

This is a series of post in which we will be discussion about the Entity Framework Code First. In this post we will be discussing how we can create a simple database oriented application using Entity Framework 4.2 released Nov, 2011. This post assumes that you have SQL Server Express installed on your machine with its Database engine and Management Studio.

Let's create a console application, named EFCodeFirstDatabaseCreation. In order to use the features of Entity framework, we need to add EntityFramework Nuget to the project. [Introduction to Nuget]


In this example, we would consider a simple application to maintain data about students. We would seed testing data using initializing code. We would be querying this data using Entity Framework Code First. Let's first define Student entity. As we can see this is a simple POCO (Plain Old CLR Object) based class with a few auto-implemented properties. Most certainly, we don't need to inherit it from any special class.
namespace EFCodeFirstDatabaseCreation.Entities
{
    class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int GradePointAverage { get; set; }
        public bool IsOutStanding { get; set; }
    }
}


Now we need to define the DbContext for querying the entities from Database. Here Entities are defined in terms of DbSetbased properties. We can query the database using these properties. It also supports insert / update and delete operations on these entities.
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Data.Entity;

    class InstituteEntities : DbContext
    {
        public DbSet<Student> Students { get; set; }
    }
}


Now we need to insert seed data to the database. The initializer can inherit from one of the following:
  1. DropCreateDatabaseAlways<T;Context>
  2. DropCreateDatabaseIfModelChanges<T;Context>
  3. CreateDatabaseIfNotExists<T;Context>

All of the above three initializers are basically the implementation of IDatabaseInitializer<T;Context>. Basically Code First supports automatic creation / updates of the Database based on POCO entities. These implementations specify what circumstances should cause creation of a new Database. By default the name of the database would be based on the name of class inheriting from DbContext and its namespace. e.g. for our case it is EFCodeFirstDatabaseCreation.Entities.InstituteEntities. We can specify a different name by causing the relevant constructor of DbContext (base class) to be used. So if we just update the code as following then the name of created database would be InstituteDB.
public InstituteEntities()
    : base("InstituteDB")
{ }

As discussed above, we add InstituteDatabaseInitializer to the project. As you can see we are adding four students to the database. It seems all four of them are outstanding :). Calling base class's seed method would cause data to be pushed to the database saving the changes in the entities.
namespace EFCodeFirstDatabaseCreation
{
    using EFCodeFirstDatabaseCreation.Entities;
    using System.Data.Entity;

    class InstituteDatabaseInitializer : DropCreateDatabaseAlways<InstituteEntities>
    {
        protected override void Seed(InstituteEntities context)
        {

            Student student1 = new Student()
            {
                FirstName = "Muhammad",
                LastName = "Siddiqi",
                IsOutStanding = true,
                GradePointAverage = 3
            };


            Student student2 = new Student()
            {
                FirstName = "Chattan",
                LastName = "Shah",
                IsOutStanding = true,
                GradePointAverage = 4
            };

            Student student3 = new Student()
            {
                FirstName = "Imran",
                LastName = "Ashraf",
                IsOutStanding = true,
                GradePointAverage = 4
            };

            Student student4 = new Student()
            {
                FirstName = "Jawad",
                LastName = "Qureshi",
                IsOutStanding = true,
                GradePointAverage = 4
            };

            context.Students.Add(student1);
            context.Students.Add(student2);
            context.Students.Add(student3);
            context.Students.Add(student4);

            base.Seed(context);
        }
    }

}

Now we just need to query the database after seed data is inserted. We can use this data for our testing. Just first initilze the database using the InstituteDatabaseInitializer defined above. Then we are just printing student's data to the console.
namespace EFCodeFirstDatabaseCreation
{
    using System.Linq;
    using EFCodeFirstDatabaseCreation.Entities;
    using System.Data.Entity;
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer<InstituteEntities>(new InstituteDatabaseInitializer());
 
            InstituteEntities instituteEntites = new InstituteEntities();
            var students = instituteEntites.Students.ToList<Student>();

            foreach (var student in students)
            { 
                Console.WriteLine(
                            string.Format("Name : {0} {1}, GPA : {2}", 
                                       student.FirstName,
                                       student.LastName,
                                       student.GradePointAverage));                                       
            }

            Console.ReadLine();
        }
    }
}
When we run the application, it shows the following output. This shows that the correct seed data is inserted to the database.


The interesting thing to notice is that we are not specifying any connection string anywhere in the application and yet we are able to run the application without any issues. This is only possible if you have local SQL Express installed on the development machine, otherwise, we can specify the connection string in the app.config. We can also access the same database using a query tool. In the following, we are connecting this using SQL Management studio and querying the student's data. Notice the same data as seeded by the application.


Download :

Friday, December 23, 2011

WPF 4.5 - Accessing DataBound Collections on Non-UI Thread

WPF has ItemsControl to show a collection of items. In MVVM, ItemsControl is data-bound with a collection in the view model. These collections might take a long time to load when the form is being shown. They might be constantly updated throughout the life cycle of the view. If we do it in the main application thread then it might cost the responsiveness of the application. Hence the need for a background thread for these operations. Well, the world has not been so simple.


As we know that the UI elements have affinity to the UI thread in WPF. It also does not allow playing with the elements collection bound as DataSource on any thread other than UI thread. And believe me, this really hurts !!! All we had were a few workarounds but no real solution. With WPF 4.5 Developer's preview, the situation improves a little. It is a step forward in the direction for providing these updates in some other thread. Although I do think that the way it is provided could be a little better than that but whatever makes my collection available to a non-UI thread. I don't really mind.

Let's understand this neat feature by creating a simple example. Let's have a simple view with a ListBox. The ListBox is supposed to display the history of signals received from a central server.


We can design the above view in XAML as follows:
<Window x:Class="MVVMCollectionNonUIThread.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MVVMCollectionNonUIThread"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Border Background="Navy" Grid.Row="0">
            <TextBlock Text="WPF 4.5 - Collections Access Across Threads" FontSize="20" 
                       Foreground="White" FontWeight="Bold"
                       TextAlignment="Center" VerticalAlignment="Center" />
        </Border>
        <ListBox Margin="3,5,3,5" Grid.Row="1" ItemsSource="{Binding RandomList}"  />
    </Grid>
</Window>
The above view has MainWindowViewModel set as the DataContext. It expects the DataContext to have a collection, named RandomList. This collection is data-bound to the ListBox so it should have the history of instances when the signal is received from the server. Now let's start defining the view model as per expectation.
namespace MVVMCollectionNonUIThread
{
    using System.Collections.ObjectModel;
    using System.Timers;
    using System.Windows.Data;

    class MainWindowViewModel
    {
        Timer _t1;

        ObservableCollection<string> _randomList;
        public ObservableCollection<string> RandomList
        {
            get
            {
                if (_randomList == null)
                {
                    _randomList = new ObservableCollection<string>();
                }

                return _randomList;
            }
        }

        public MainWindowViewModel()
        {
            _t1 = new Timer(300);
            _t1.Elapsed += new System.Timers.ElapsedEventHandler(_t1_Elapsed);
            _t1.Start();
        }

        void _t1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            RandomList.Add(string.Format("Signal Time : {0}", e.SignalTime));
        }

    }
}
In order to simulate the signal reception, we have used System.Timers.Timer. The timer would tick after at least 300 ms. This event is handled by _t1_Elapsed. We are just adding an item to RandomList each time the timer ticks. This event handler is to simulate the signal received from the server. Generally, this client / server communication is handled on a different thread like this handler. Since we are following through this post, if we run the application this results in the EXPECTED exception when the item is being added to RandomList in _t1_Elapsed (non-UI thread) [This is generally UNEXPECTED and comes as a surprise if developer doesn't know about it yet.]


FYI: In Winform, we can cause Elapsed event for System.Timers.Timer to be raised in UI thread by setting the SyncrhnizingObject property. We have discussed about this in our timers discussion [http://shujaatsiddiqi.blogspot.com/2010/10/timers-for-net-applications.html]

WPF 4.5 Developer's preview has provided certain new static methods in BindingOperations class to fix this behavior. The list of new methods I could find is as follows:
  1. AccessCollection
  2. DisableCollectionSynchronization
  3. EnableCollectionSynchronization
This also have some overloads. Let's see how we can fix our little example with these methods. We really can go around by just using EnableCollectionSynchronization. It is to report a collection to be accessible in non-UI threads. In order to provide thread synchronization, we need to provide the synchronization mechanism. Simply we can use the overload which needs lock object. Let's update the view model as follows:
namespace MVVMCollectionNonUIThread
{
    using System.Collections.ObjectModel;
    using System.Timers;
    using System.Windows.Data;

    class MainWindowViewModel
    {
        Timer _t1;
        object _lockObj = new object();

        ObservableCollection<string> _randomList;
        public ObservableCollection<string> RandomList
        {
            get
            {
                if (_randomList == null)
                {
                    _randomList = new ObservableCollection<string>();
                }

                return _randomList;
            }
        }

        public MainWindowViewModel()
        {
             BindingOperations.EnableCollectionSynchronization(RandomList, _lockObj);

            _t1 = new Timer(300);
            _t1.Elapsed += new System.Timers.ElapsedEventHandler(_t1_Elapsed);
            _t1.Start();

            
        }

        void _t1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            RandomList.Add(string.Format("Signal Time : {0}", e.SignalTime));
        }

    }
}
Here we just have added BindingOperations.EnableCollectionSynchronization to the view model's contructor for the RandomList collection. We have used the instance member _lockObj as the lock object. That's it! Let's run this now!


Download:

Wednesday, December 21, 2011

WPF 4.5 Developer's Preview - Delay Binding

In this post, let's discuss one great feature of Binding as in WPF 4.5 Developer's preview. This feature is called Delayed Binding. As a XAML technologies developers we are specially concerned about the timing when the values are copied between SOURCE and TARGET of binding.

From the very early stages, human has tried finding answer of this question. Who am I? Even famous eastern poet Bulleh Shah explained in one of his master piece.

Not a believer inside the mosque, am I
Nor a pagan disciple of false rites
Not the pure amongst the impure
Neither Moses, nor the Pharoh
Bulleh! to me, I am not known

Since WPF / Silverlight has very sophisticated Binding, the difference between Source and Target is blurred. Now the main question is what should be called Source and what should be considered as Binding Target. Although the question is not a philosophical one but we clearly need a way to identify the source and target of Binding. Charles Petzold makes it easier by calling Binding Target to be the one where the Binding is actually defined. Now the other party becomes the Binding Source. So if TextBox.Text is bound to FirstName property of the DataContext then TextBox.Text becomes the Binding target and hence DataContext.FirstName might be taken as Binding source.

From Target to Source, we control the timing by using UpdateSourceTrigger property of Binding. As we know that it has three possible modes. PropertyChanged, LostFocus and Explicit.

From Source to Target, this flow of update happens based on the nature of Source property. Generally, the view models implement INotifyPropertyChanged interface. Now setting the property causes PropertyChanged event to be raised. Binding Target listens to this event and update itself. The event has the details which property of the DataContext is updated which makes it easier for the runtime to update the view. The source property might be a DependencyProperty. As we know one of the feature of DependencyProperty is change notification. As WPF runtime receives such notifications, it propagates these changes to the Binding system, which causes updating the target's value.

The direction of flow of these updates are controlled by Binding mode. Different XAML technologies can have different default mode of binding. There are three different Binding modes in WPF / Silverlight. These Binding modes are as follows:

  1. TwoWay
  2. OneWay
  3. OneTime
  4. OneWayToSource
  5. Default
Except possibly Default option, the modes which support flowing the value updates from Target to Source are OneWayToSource and TwoWay. It must be noted that the feature we are discussing in this post only applies to this case when the updates are propagated from Target property to Source property.

Now the main question is why we need this delay? Basically it is to provide a compromise between two selections for UpdateSourceTrigger. These selections are PropertyChanged and LostFocus. With LostFocus, the binding system waits until focus is lost from the target control. So all these intermediate updates are lost. If this is a TextBox, the user might expect immediate response from the system. Since updates are not flowing from Target to source, no converters are applied. Similarly none of the validation rules are used. This might be frustrating for the application's user. On the other hand, if we change this to be using PropertyChanged, all the updates are propagated from Target to Source which might involve value conversion and validation. These operations might cause expensive logic to run. When we are using the control, we don't want to wait until we change focus to the other control. But we, definitely, don't want to run all of this with every key stroke or any other way in which user interaction is causing Target value to be updated. We need a mechanism similar to throttling which helps us in this regard. Binding Delay is just for the same purpose.

Let's create a simple WPF project MVVMDelayedBinding as follows:

Let's add a simple view model. The view model implements INotifyPropertyChanged interface. The view model just has one property FirstName. We will be binding this property to a TextBox in the view. Since we would just be binding this to support the flow of value update from Target to Source, it wouldn't really matter if this supports change notification or not. As a Binding Source, the only requirement is that the source should be a property, change notification support is just to update target from the property updates in the source.

namespace MVVMDelayedBinding
{
    using System.ComponentModel;

    class MainWindowViewModel : INotifyPropertyChanged
    {
        private string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }

        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
        
    }
}
Since this is a WPF 4.5 Developer's Preview feature, we need .net framework 4.5 installed on the machine. We also need Visual Studio 11 Developer's Preview. Let's open this in the IDE and update the framework to .net framework 4.5.

Now let's update MainWindow.xaml as follows:

<Window x:Class="MVVMDelayedBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MVVMDelayedBinding"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="45" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.20*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Border Background="Navy" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" >
            <TextBlock Text="Personal Information" Foreground="White" FontSize="20"
                       TextAlignment="Center" FontWeight="Bold" VerticalAlignment="Center"/>
        </Border>
        <Label Content="First Name" Grid.Row="1" Grid.Column="0" Margin="2,3,2,2"/>
        <TextBox Grid.Row="1" Grid.Column="1" Margin="2,3,2,2" >
            <TextBox.Text>
                <Binding Path="FirstName" 
                         Mode="OneWayToSource" 
                         UpdateSourceTrigger="PropertyChanged"
                         Delay="200" />
            </TextBox.Text>
        </TextBox>
        <Border BorderBrush="Silver" BorderThickness="1" 
                Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2">
            <TextBlock Text="Other Details" TextAlignment="Center"
                       VerticalAlignment="Center"
                       FontSize="20"/>
        </Border>
    </Grid>
</Window>
This is simple example of MVVM based view. We are using the new MainWindowViewModel instance as the DataContext of the view. The most interesting thing is the TextBox Binding. We are binding the TextBox with FirstName property from the DataContext. The mode is set as OneWayToSource supporting the flow of value updates only from Target to Source. The UpdateSourceTrigger is set as PropertyChanged, resulting in the updates in the Target properties to be copied to the Source without waiting for losing the focus. Now look at the Delay. We are setting the delay as 200. This is in milliseconds. It means the runtime should wait for 200 ms to copy a property update to the Source. This would throttle fast changes to the view and wait for the interaction to get settled before the view state gets updated. Let's run this and use the First Name as Muhammad. Instead of the regular behavior of PropertyChanged. It throttled my input, waited for 200ms and updated the view model's property. This is perfect!

Download: