Introduction

In this article, I will describe a small proof of concept project for an idea which has been floating around for a long time, but doesn't seem to have a name. I've dubbed it the 'code-first user interface', by analogy with code-first development in Microsoft Entity Framework. Its main goal is to greatly reduce the amount of work required to create a program's user interface.

I need to apologize here for the incompleteness and inconsistencies in the code. I've been working on it for ages during my limited spare time, so I felt I had to get the article out before I died of old age. Also I'd like to get some early feedback, to see if this idea is worth pursuing. Please bear with me.

But I'm going to start with some complaints...

Don't Repeat Yourself

The impetus behind this is simply to reduce the amount of code required to implement a user interface. Currently, UI development seems to entail writing the same thing in multiple ways. For instance, recently I had to create a small test program as part of my professional work. It was a WPF application to display and edit items in a list. I've recreated a simplified version of it here. I started with this class like this:

I feel this is all a bit mechanical and repetitive. And we are repeating the same information - the names of the properties, the type and so on. This is clear if we need to add a new property to the class - we will have to add it in three places, not just one. We have to add it to the class, the XAML for the list and the XAML for the form. We could almost write an algorithm:

for each public property of the class
add a column to the list view and bind it to the property
add a label and field to the form, and bind it to the property

I feel we need to apply two of the fundamental principals of programming here:

Don't repeat yourself (DRY)

If it's repetitive and mechanical, automate it.

Too Many Files

Another problem I have with current user interface development is the amount of 'cruft' it requires. For example, if you fire up Visual Studio Community and create a sample MVC project, here's what you get:

We end up with 191 files in 33 folders, taking up over 9 MB! But the real essence of this application can be described with just a couple of objects - the TodoItem and the TodoItemList in the Model folder. So my question is why do I need to see all these views, controllers, data transfer objects, JavaScript and CSS files? I feel this is making application development more complex than it should be.

The Code-First User Interface

My proposal is that we simplify user interface code by adopting a method similar to code-first development in Microsoft Entity Framework. In the code-first approach, we can concentrate on the design of our 'domain' entities without having to write separate code to map them to database tables. We just code the classes that describe our application and the mapping is done automaticaly, using sensible conventions:

A mapping layer (the Object-Relational Mapper) is responsible for translating our model classes into relational database tables. [This article is a good introduction to the subject: http://msdn.microsoft.com/en-us/data/jj193542.]

The code-first user interface works the same way, but now a mapping layer (the Object-UI Mapper) creates the user interface using 'reflected' information about the model classes:

So we can just code the model classes, and the OUIM is responsible for creating the user interface. If we modify a model class, no further changes are required - the mapping process will recreate the UI. Furthermore, we could create user interfaces for different UI frameworks without having to rewrite most of our application. We just change the OUIM.

The efficacy of this does rely on a few assumptions, however:

There is a one-one mapping between model objects and their views.

There is a one-one mapping between properties of model objects and either list columns or form fields.

We can infer the appearance of the UI by using the type information of the properties and a small number of attributes.

There will be cases were these assumptions do not hold, but in my experience this covers a large swathe of an application's user interface.

Existing 'Code-First UI' Systems

There are a couple of existing examples of this approach that you may already be familiar with: the Windows Forms Property Grid and Dynamic Data Entities.

Property Grid

Here's what we get if we drop a Windows Forms PropertyGrid onto a form and bind it to a ProductItem object, as defined above:

We have very quickly generated a user interface to edit our object, but I think we could fairly describe it as 'Spartan'. We can edit all the fields, but we are stuck with just a text box for most of them.

Dynamic Data Entities

Dynamic Data Entities for ASP.NET allows us to quickly create a user interface from a data model. We just define this:

Then, we automatically get a list view and an editing form, like this:

This is exactly the kind of thing we want - the user interface has been generated for us just using the type information in the model. But:

It only works for the web

We still don't get those up/down controls for the numeric fields.

There are still lots of additional files added to the project that we probably don't need to see:

Sample Implementation

To demonstrate the code-first approach I've implemented a small demonstration project, which you can download using the links at the top of the article. In this section, I'll go through some of the major features of the object-UI mapping. For starters though, here's what we get if we use it to display a Product object as defined above. The code required to do this will be trivial:

ProductItem product = new ProductItem();
UI.ShowDialog(product);

This is the result (I've added some more fields in this incarnation):

Hopefully, this would be more acceptable to an end-user than the property grid shown above.

Now I'll present some examples of the code to UI mapping in more detail.

Simple Text Field

The simplest case is just a string property without any additional attributes:

publicstring simpleTextField { get; set; }

Result:

We get a label and a single-line TextBox. Note that we have not had to specify the label to use for the control - it has been derived from the property name by splitting it on each capital letter. So if our properties follow the 'camelback' naming convention, we will get acceptable labels.

Future Development

There are numerous ways this code could be improved and developed. Here are some I've thought of so far:

Different UI frameworks. I've implemented for Windows Forms, as that's what I have most familiarity with. But it would be good if we could also create an interface for the web, and for the new Microsoft 'Universal Apps'.

Actions. Currently we only support editing data. It would be good to extend the interface generation to support actions. For instance, public methods marked with an [Action] attribute could be used to add a button to the form, which calls the method when clicked.

Attributes. At the moment, the code is only interpreting its own attributes and a few from System.ComponentModel. It should be extended to garner useful information from System.ComponentModel.DataAnnotations.

Groups. If properties have a group attribute, we could perhaps put them on separate tabs.

I heard that you are using a DB to map objects..if not, it will be interesting to give a new feature, a way to store data values into a single writer/reader abstraction class which can be override to save data values into a DB or into a single file, or, else any media and add a cache file.

The problem of keeping a consistently data values across all modal dialog and as a way to keep old values and replaces them if cancel button is clicked : I say, a transaction (like a commit/rollback in a database)

Sir - this looks like a nice start. I would strongly encourage you to put this project on GitHub and allow people to fork it, and/or send you pull requests to improve this tool. If you got a few interest co-developers, you could really get this thing to have some real adoption out there.

Amazing work here, thanks for sharing it with the rest of us. You might try putting this on github if you are interested in collaboration with others could see myself making pull requests to something like this to expand functionality

You are not the first and will not be the last who automates these kinds of things

Your approach is very nice - I am deep into WinForms since 2002 and have my own libraries for this - so yes, keep it up IMHO - and if it is just for your personal time savings when prototyping something or creating the 2001st form for that stupid base data table in your sqlite db!

I am currently working on something similar, attributes based too, but I want to transfer data from a database to a binary buffer (memory stream) and send it over tcp to a recipient - and that all without writing the code for it - just through some generic engines that work with attributes (and locally cache the reflection method info's once determined to increase performance)

so 5 from me because we share the same approach when we think about a task

Yes I should have included localization in the 'Future Development' section. There is a hook for this in the code though - the labels are generated by calling the class NaturalLanguageSystem, with the idea being that it could delegate to different implementations. So you could access a resource file, or even call Google Translate to get your localized labels.