30-Storey building built in 15 Days, how long needed for a simple Todo Application?

Things are moving a lot faster nowadays.  The expectation on speedy delivery is higher in all areas, including logistics, manufacturing, software development and in this case construction. However,  people expect more other than speed, but quality, consistency, as well as predictability.

Similar to Industrial Revolution in manufacturing, the transition to new processes of software development is necessary.

To build in speed, a well and careful planning, and of course standardization are required.

Yes, the building looks decent and similar to most of the buildings you can find in the city. However, we must admit that it serves its purpose well, just like most of the buildings can be found everywhere. Cost-benefit equation must be balanced on both side.

Looking back, how fast we can in building an application, let’s say simple to do list application, a fully usable application, storing records and updating records. We are not looking for most fanciful desktop application, but with decent look.

The answer given by Grassland System is 73 lines of C# code. Yes, these 73 lines of code must describe precisely the data to be stored, behavior and the look.

Actually I did not count line by line. It is done by VisualStudio. Not sure why TodoState is counted as 0 line though.

So how much can be done from this code. This is the result.

In this simple example, only C# code is needed. No WPF/Xaml knowledge is required.

This is how we spend our line of codes. Refer to Code Metric Result screenshot.

We start with most important part: Domain for Todo

    public class Todo : GrasslandAuditable
    {
        [ItemIdentifier]
        [DataType(DataType.MultilineText)]
        public string Content { get; set; }
        public DateTime? Deadline { get; set; }
        public TodoState TodoState { get; set; }
        public DateTime? StartTime { get; set; }
        public string Location { get; set; }
    }

Most of the code are self-explanatory. Only [ItemIdentifier] is used to allow user to identify particular item, say for example: ItemCode of a product, name of customer etc.  The domain will is used to generate database be it SQL Compact, MS SQL, MySQL through EntityFramework. Any kind of Database you can used so long you have the connector.

Following MLAWD model, we move on to Menu

    [SideBar(Header = "Todo", Icon = "Calendar", Color = "CornFlowerBlue")]
    public class TodoMenuV : MenuItemV { }

    public class TodoMenuVM : MenuItemVM
    {
        public TodoMenuVM()
        {
            var newquery = new UriQuery();
            newquery.Add("new", "new");

            this.SetMenuAction("To Dos", () => NavigationService.RequestList(typeof(TodosV), DisplayMode.View))
                .SetMenuAction("Manage To Dos", () => NavigationService.RequestList(typeof(TodosV), DisplayMode.Edit))
                .SetMenuAction("New To Do", () => NavigationService.RequestWork(typeof(TodoEditV), newquery));
        }
    }

Menu is simple accordion, where developer only need to set the name of the link and the action. Notice the attribute is used to describe the look of the Bar ie. Image/Icon, Name and Color.

Now is L – List

    public class TodosV : ListV { }

    public class TodosVM : ListVM<Todo>
    {
        public TodosVM()
            : base(null, typeof(TodoEditV), typeof(TodoActionV))
        {
            this.SetColumn(x => x.Content, width: -1)
                .SetColumn(x => x.TodoState, searchable: false)
                .SetColumn(x => x.Deadline)
                .SetColumn(x => x.StartTime);
        }
    }

Through the use of fluent interface and lambda expression.  List can be setup in seconds and mistake can be lowered to minimum. Notice, width is set to -1 means to 1* in xaml width, where as positive means pixel. As we pass in W – Work in List, so it wired up automatically when user allowed to update, create or delete particular items.

ListVM comprises of few components each manage certain functionality such as Search & Filter and Sort, Pagination, Multiselection,  Delete, Update, Create, Selection handler etc.

ListVM (VM means ViewModel by the way) are not talking to Database directly. It calls through Service Interface and in this case, default service instance will be generated and injected in run time.

Now, let’s move on to A – Action

List sometimes trigger action which is a bar on top. Specific action can be done on particular selected item.

    [RibbonContextual("To Do List", "LawnGreen")]
    public class TodoActionV : ActionV { }

    [AutoCommands]
    public class TodoActionVM : GrasslandMenuVM<Todo>
    {
        [AutoCommand]
        [GrasslandActionTab(GroupName = "Operation",
            Icon = "Pencil", Color = "CornFlowerBlue")]
        private void Edit()
        {
            var query = new UriQuery();
            query.Add("id", Model.Id.ToString());
            NavigationService.RequestNavigateAction(typeof(TodoEditV), query);
        }

        [AutoCommand]
        [GrasslandActionTab(GroupName = "State",
            LargeImage = "/Grassland.Infrastructure;component/Images/document_mark_as_final.png")]
        private void inProgress()
        {
            Model.TodoState = TodoState.InProgress;
            SaveOperation();
        }

        private bool canInProgress()
        {
            return Model.TodoState != TodoState.InProgress;
        }

        [AutoCommand]
        [GrasslandActionTab(GroupName = "State",
            LargeImage = "/Grassland.Infrastructure;component/Images/document_mark_as_final.png")]
        private void completed()
        {
            Model.TodoState = TodoState.Completed;
            SaveOperation();
        }
    }

RibbonContextual is used to describe the look of Action tab. As for View Model, Action button is generated based on assigned attribute, this draws the similarity of WebAPI controller where attribute describes exposed interface to the user. AutoCommand attribute actually just a shortcut to generate delegate command and ICommand. This small attribute really help us in remove great number boilerplate codes and improves readability.
our Non-UI & Non-WPF Developer, web Developer or pure C# Developer finds more comfortable this way, as they do not have knowledge about ICommand or DelegateCommand by PRISM. Note, ‘Can’ and ‘Show’ method can be added to determine whether showing the button or enable/disable the button.

    public class TodoEditV : WorkV
    {
        public TodoEditV()
        {
            AutoField.SetFieldType(this, GenerationType.Edit);
        }
    }

    public class TodoEditVM : WorkVM<Todo>
    {
        public TodoEditVM()
        {
            this
                .AddField(() => Model.Location)
                .AddField(() => Model.TodoState, newLine: true)
                .AddField(() => Model.Deadline, newLine: true)
                .AddField(() => Model.Content, 3, true, 9, 80);
        }
    }

Now is the W – Work. In this example, we only create a edit interface. Of course, we can add an view interface too. SetFieldType let the UI/WPF changes the field type to Editing.
Same case with list, using fluent interface and lambda expression, we can add in the field easily. Field are generated based on type. Through the use of UIHint attribute, and DataType attribute, sometimes we can change the resulted field type of display as well as edit. For example, combo box to radio button, date picker or time picker or date time picker.

WorkV (View) is the view for standard form. Its comprises of different components. Responsive Grid, a special WPF Grid system same as the Grid System commonly used in Web design, particularly Bootstrap. This concept inevitably helps us in realizing UI generattion. Same with most popular system, ResponsiveGrid using 12 column system and by default all fields occupied 3 column. The other components the DynamicControls. It generates Label, Display and Editor. Display and Editor is then combine in AutoField which changes to Display to Editor or vice versa based on attached dependency property set.

There is it. About 51 lines of code described here. The rest of 22 lines of C# code is more of initializing database, setting up a module that Grassland System can recognize.

The example here is using Top Level of Grassland API which doing all User Interfaces generation particularly helpful those developer not so into XAML/WPF, MVVM. For those have knowledge about WPF/XAML, there is always a choice to substituting it with customized UserControl and ViewModel class.

We are looking for technology evangelist worldwide to work together improving Grassland as well as bringing affordable and reliable software solution to people who need it in a very short time frame.

Feel free to contact me directly at keyeng@gneysoftware.com or whatsapp me @+60167328125 OR @+6591330938

 

 

 

 

 

 

 

 

 

facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply