A discussion about Rich Internet Applications, and user experience focusing on architecture, design patterns and methodologies.

Tuesday, November 9, 2010

Dynamic Entity Binding

Silverlight provides a powerful binding mechanism to allow a comprehensive solution for data transport and validation.  Unfortunately, this binding relies on a hard coded model for implementation.  In the scenario where the schema of the data entity is not known at compile time, there is nothing provided out of the box.

I have come up with a fairly generic solution that stores data in a dictionary type construct with validation  and localization support, leveraging Silverlight’s exiting binding infrastructure.

For this blog post, I will focus on the core classes for binding support, with subsequent updates for validation and localization.

The main class for this solution is the DynamicEntity.

The data and metadata are stored in a private dictionary, and a public indexer overload provides public access directly to the data (necessary for the binding declaration). The key thing to understand here is that binding on a dictionary type object requires collection change notification, not property change notification, to work.  I have included property change notification for additional flexibility.  The field class contains the field metadata and the value.

    public class Field
    {
        public FieldMetadata Metadata { get; set; }
        
        public object Value { get; set; }
    }


The field metadata contains properties with meta-information about the field, including name, description, and type.  In a future blog post, I will add validators and localization support as well as describe a label control that functions like the SDK Label.



To use this, we can expose the entity as a property in our ViewModel as follows:



public DynamicEntity Entity { get; set; }
        public MainPage()
        {
            
            Entity = new DynamicEntity();
            FieldMetadata field = new FieldMetadata(typeof(string), "FirstName", "FirstNameLabel" , "FirstNameDescription", typeof(Strings));
            field
                .AddValidator("FirstName", new RequiredValidator("FirstNameRequired"))
                .AddValidator("FirstName", new StringLengthValidator("FirstNameStringLength") { MaximumLength = 40 });
            
            Entity.AddField(field, "Carlos");              
            
            DataContext = this;
            this.InitializeComponent();
        }


… and then we bind as follows:



<TextBox x:Name="textBox" Text="{Binding Entity[FirstName], Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnNotifyDataErrors=True}"/>


I will be posting the source code with all the features (validation, localization) on my codeplex site with the last post in this series.

About Me

My photo
Toronto, ON, Canada
I am a technical architect at Navantis, with over 12 years experience in IT. I have been involved in various projects, including a Hospital information system called CCIS for which my team received the 2007 Tech-Net innovation award. I have been working with Silverlight since beta 1, and am very keen on practically applying this technology and WPF to line of business applications.