I have various forms on my application and I wanted to be able to see how much had been filled filled out, so I wrote this helper class that I could use to measure how much of the pages view model had been completed.

It uses reflection to check each of the fields in turn, simply checking whether the field is null or not. It’s a bit rough around the edges, and doesn’t really have a strategy for dealing with nullable data types (it simply ignores them) but it worked, and stopped me needing to write 10 different classes to measure 1 different view models so I was happy! It also ignores fields ending with Id, and the ignore rules can be easily extended. The other thing it does is keep track of any ignored fields, and any that it wasn’t able to count (ie. nullables). I never actually used these lists, but they come in pretty helpful during debugging I find.

public class ViewModelProgressHelper
{
    public static ViewModelProgressReport Process(TModel model)
    {
        var report = new ViewModelProgressReport();
        var fields = model.GetType().GetProperties();
        foreach (var field in fields)
        {
            if (Ignore(field.Name)) report.IgnoredFields.Add(field.Name);
            else if (field.PropertyType.IsGenericType && field.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                report.NumberOfFields++;
                if (field.GetValue(model, null) != null) report.FieldsCompleted++;
            }
            else if (field.PropertyType == typeof(string))
            {
                report.NumberOfFields++;
                if (!string.IsNullOrEmpty((string)field.GetValue(model, null)))
                    report.FieldsCompleted++;
            }
            else if (field.GetValue(model, null) == null)
                report.NumberOfFields++;
            else if (field.PropertyType.IsValueType)
            {
                var defaultValue = Activator.CreateInstance(field.PropertyType);
            }
            else report.UnrecognisedFields.Add(string.Format("{0} ({1})", field.Name, field.GetType().Name));
        }
        return report;
    }

    private static bool Ignore(string name)
    {
        return (name.EndsWith("Id")); // Ignore primary/foreign keys
    }
}

public class ViewModelProgressReport
{
    public ViewModelProgressReport()
    {
        IgnoredFields = new List();
        UnrecognisedFields = new List();
    }
    public int NumberOfFields { get; set; }
    public int FieldsCompleted { get; set; }
    public double Percent { get { return NumberOfFields > 0 ? ((double)FieldsCompleted / NumberOfFields) * 100 : 0; } }
    public List IgnoredFields { get; set; }
    public List UnrecognisedFields { get; set; }
}
Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks

One thought on “View Model Completion

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>