Syncfusion’s latest datagrid

I’ve been looking forward to Syncfusion’s latest release of their Silverlight components (and it’s out today). In particular, their new SfDataGrid datagrid is reaching maturity so I decided to take it out for a quick spin, and verdict is out. Two thumbs up. Well done. Their API is intuitive and much improved from their original DataGrid. It is different, so don’t expect to be able to port over existing code easily, but there is considerably less code to port.

We’ll start off with a simple model

namespace SyncfusionGridDemo.ViewModels
{
    using System.ComponentModel.DataAnnotations;

    public class Customer
    {
        [Display(Name="Full Name")]
        [Required(ErrorMessage="{0} is required")]
        public string FullName { get; set; }

        [Range(18, 80)]
        public int Age { get; set; }
    }
}

As you can see there is not much to it, and we’ll create a viewmodel and host a collection of Customers.

namespace SyncfusionGridDemo.ViewModels
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;

    public class MainPageViewModel
    {
        private IList<Customer> _addedCustomers = new List<Customer>();
        private IList<Customer> _deletedCustomers = new List<Customer>();

        public MainPageViewModel()
        {
            Customers = new ObservableCollection<Customer>(new[]
            {
                new Customer { FullName = "Marcus Aurelius", Age=30 },
                new Customer { FullName = "Dana Fausbinder", Age=3 },
                new Customer { FullName = "Tomoko Cressida McManus", Age=54 },
            });
            Customers.CollectionChanged += Customers_CollectionChanged;
        }

        void Customers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    // TODO these will need to be saved to the database
                    _deletedCustomers.RemoveRange((IEnumerable<Customer>)e.NewItems);
                    _addedCustomers.AddRange<Customer>((IEnumerable<Customer>)e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    _addedCustomers.RemoveRange((IEnumerable<Customer>)e.NewItems);
                    _deletedCustomers.AddRange<Customer>((IEnumerable<Customer>)e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    // TODO these will need to be saved to the database
                    _deletedCustomers.RemoveRange((IEnumerable<Customer>)e.OldItems);
                    _addedCustomers.RemoveRange((IEnumerable<Customer>)e.OldItems);
                    _addedCustomers.AddRange<Customer>((IEnumerable<Customer>)e.NewItems);
                    break;

            }

        }

        public ObservableCollection<Customer> Customers { get; set; }
    }

    public static class CollectionExtension
    {
        public static void AddRange<T>(this IList<T> coll, IEnumerable<T> items)
        {
            foreach (var item in items)
            {
                if (!coll.Contains(item))
                    coll.Add(item);
            }
        }

        public static void RemoveRange<T>(this IList<T> coll, IEnumerable<T> items)
        {
            foreach (var item in items)
            {
                if (coll.Contains(item))
                    coll.Remove(item);
            }
        }


    }
}

And now let’s bind to Syncfusion SfDataGrid


        <Grid:SfDataGrid 
            AllowEditing="True" 
            Grid.Row="1" 
            ItemsSource="{Binding Customers}" 
            x:Name="SampleGrid" 
            GridValidationMode="InEdit" 
            AddNewRowPosition="Top"/>

and the result is rather good for so little work.

Some minor criticism

The datagrid is not aware of IEditableObject interface. This interface supports BeginEdit(), EndEdit() and CancelEdit(). This allows the user to revert the record’s changes using the escape key.

Overall, the user experience is much improved. Thanks again for listening to my concerns.