Sunday, July 22, 2012

CSLA and Visual WebGUI


I don't like ASPX. I tried both flavours, with and without AJAX. I hate several things about ASPX
  • programming in 4 languages (C#, HTML, Javascript, CSS)
  • ViewState
The normal way to write ASP.NET applications is to write stateless pages. You can use a state server but most of time you just use ViewState. Neither one is a good solution. ViewState means your server sends the browser an invisible field with state information. When you post back, the ViewState information travels back to the server. As you might imagine, all this data that is sent back and forth doesn't help your Web application to become faster.

The worst part of ASP.NET is the 4 language issue. I guess I don't need to explain in detail why it doesn't help to simplify the development process or to make it faster for that matter.

Enter Visual WebGUI. No ViewState and only one programming language: C# or VB.NET.

For those unfamiliar with Visual WebGUI, it's a WEB framework that is build around the "empty client" concept. All the developer sees is the full set of Windows Forms controls. You write your code on C# or VB.NET and forget Javascript, CSS and HTML exist. If you have a working Windows Forms application, porting it to WebGUI is really easy. The browser is used just to display the visual side of the controls and to return user input back to the server - the concept of "ViewState" doesn't exist.
  • The browser is running a JS kernel that relays low level events to the server: user pressed a key, user clicked at point (X,Y), etc.
  • The library handles the low level events like the Windows Forms library does.
  • The server is running your application and it doesn't need to reload state everyt time you click somewhere.
This results in applications easier to write:
  • one development language only
  • you don't loose context between page submissions (you don't have to submit pages)
and applications that run faster
  • less data flows server => client => server (namely ViewState)
  • application doesn't need to reload context from BD or whatever
Going back to Visual WebGUI sounded like a good idea. From my past experience with CSLA + Windows Forms and CSLA + WebGUI, I knew CSLA needs some UI support classes and UI controls. So I ported them to Visual WebGUI. It was really easy and it didn't came as a surprise, since WebGUI replicates the Windows.Forms namespace.

So I was developing this application. I had the BO and DAL done for CSLA Business Objects library and the UI part was well advanced. The customer wanted a WEB UI but I chose to write two UIs:
  • Windows Forms
  • WebGUI
The first is used as a test and control project. I put the ideas to screen under Windows Forms. Of course there is some overhead to take this double UI approach. The overhead isn't that big since it's so easy to port Windows Forms to WebGUI.

While it's impossible to find a UI technololy more stable than WinForms, Visual WebGUI has made some very important progress but it's not the most stable technology around. If something doesn't work under WinForms, no bother to try it under WebGUI.

The big advantage on this approach allows me to see in WinForms  what I can expect from WebGUI. If the behaviour doesn't match, I have a WebGUI issue. I could develop directly on WebGUI. If some control didn't behave the way I wanted, it would be difficult to tell whether it was the developer's fault or a WebGUI problem.

So what's the bottom line of this blog entry?

CslaContrib.WebGUI source code was posted on this CSLA.NET thread. In a couple of weeks it will be published on CSLA .NET Contrib Codeplex site too.

Sunday, June 10, 2012

MVVM FX - Windows Forms and Web


Things are moving fast. Two weeks ago I was looking for a WindowsForms MVVM framework. Today I published it at http://mvvmfx.codeplex.com/. This project used to be managed by Sam Bourton that kindly transferred project ownership to me.

Why the insistence on using the FX expression? Why not WF or WinForms? As the project title says MVVM FX - base framework for Windows Forms and Visual WebGUI, the project scope is not only WinForms but also Visual WebGUI. It's easy to port Windows Forms code to Visual WebGUI since Gizmox tryed very hard to mirror System.Windows.Forms namespace as Giszmox.WebGUI.Forms.

In case you don't know, VisualWebGUI it's an empty client technology for Web. The browser is a "dumb terminal" - a bit like the Sun Network Computer concept: the browser is used to display content and receive user input (mouse and keyboard). There is a Javascript kernel that handles display messages from the server and relays user input back to the server. Incidentally it also acts as a keep alive agent, to let the server know that the client is still there and informing the user in case the server doesn't reply. These messages are very small (nothing like the dreaded viewstate of ASPX) and the system is indeed very responsive.

All these features are wrapped as Windows Forms technology - the only desktop technology available when Gizmox started this product.

There are several consequences to using Visual WebGUI:
  1. you write code in C# or VB.NET
  2. you don't have to know Javascript unless you want to make your own low level control
  3. it's not easy to do MVVM (just like WinForms)
Number 3 above is a downside that this framework will overcome.

Tuesday, June 5, 2012

Iterating an enumerable in C#


Suppose you have an enumerable and you need to iterate it in order to do something. I know that's not a very common need but it may happen. It happened to me and I came up with this solution.


using System.Collections.Generic;

namespace Events
{
    public enum MenuItemEvent
    {
        Click,
        Select
    }

    public class MenuItemEvents : List<MenuItemEvent>
    {
        public MenuItemEvents()
        {
            var item = 0;
            while (true)
            {
                if (((MenuItemEvent) item).ToString() == item.ToString())
                    break;

                Add((MenuItemEvent) item);
                item++;
            }
        }
    }
}

Now you can foreach every element of the enum.

Sunday, May 27, 2012

WindowsForms Truss databinding


Yesterday I blogged about MVVM for WindowsForms and I mentioned Truss, the databinding library à la WPF that is UI independent. Note I said independent, not agnostic. In fact, it can bind to:
  1. an ordinary property contained in an object that implememts INotifyPropertyChanged
  2. a DependencyProperty of a DependencyObject
  3. an ordinary property of a WindowsForms control
When we say DependencyProperty you know it's WPF (or Silverlight).How come it knows how to bind to a property of a WinForms control?

Truss implements a binding strategy that uses the Microsoft PropertyNameChanged Pattern. Given a property Address, Truss attaches itself to the AddressChanged event. It happens properties of WinForms controls raise this event instead of  the PropertyChanged(<propertyname>) event that is raised by INotifyPropertyChanged properties.

A word about binding expressions

In our example, we have:
  • MainForm - the view with two text boxes: txName and txAddress 
  • MainFormViewModel - the ViewModel that contains a Model property of type MainFormModel
  • MainFormModel - the model with two string properties: Name and Address
The listing included in this post aren't MVVM examples, so I won't discuss the technical MVVM side. For this example, we pass the ViewModel reference to the view on the constructor method. On the form Load handler, we bind the model properties to the text boxes in two different ways:
  • using a simple string path expression
  • using a lambda expression
If you are going to inject your bindings using convention over configuration, you must use the first variation.

    Listing 1 - Single part path
    namespace WinFormsBinding
    {
        public partial class MainForm : Form
        {
            private MainFormViewModel _viewModel;
    
            public MainForm(MainFormViewModel viewModel)
            {
                _viewModel = viewModel;
                InitializeComponent();
            }
    
            private void MainForm_Load(object sender, EventArgs e)
            {
                var bindingManager = new BindingManager();
                bindingManager.Bindings.Add(new Binding(this.txAddress, "Text", _viewModel.Model, "Address"));
                bindingManager.Bindings.Add(new TypedBinding<TextBox, MainFormModel>(
                    this.txName, s => s.Text, _viewModel.Model, t => t.Name));
            }
        }
    }
    

    You might be tempted to refer the root object and use a multipart path.

    Listing 2 - Multi part path
    bindingManager.Bindings.Add(new Binding(this, "txAddress.Text", _viewModel, "Model.Address"));
    bindingManager.Bindings.Add(new TypedBinding<MainForm, MainFormViewModel>(
        this, s => s.txName.Text, _viewModel, t => t.Model.Name));

    Well don't. This doesn't work. I'm not sure whether this should work under Truss. I intend to come back on this subject.

    As a closing subject, on my quest for MVVM for WindowsForms I found another interesting piece of MVVM stuf. Magical.Trevor implements convention over configuration to find a View for a given ViewModel and bind both together. The same pattern is also used to self-bind:
    • Button Click event to methods
    • TextBox Text property to string properties
    Magical.Trevor isn't a port of Caliburn.Micro for WindowsForms. As Mike Minutillo says, it's based on some of the ideas found in Caliburn.Micro.

    Saturday, May 26, 2012

    MVVM for WindowsForms


    Some years ago, I became interest in MVVM for developing WPF (and Silverlight) projects. After much research, I chose Caliburn.Micro: small, simple yet powerfull. I like the convention over configuration approach. In spite of MVVM being accused of making you write more code, Caliburn.Micro's convention over configuration means it has the ability to inject the binding code and makes you write less code. Your view classes have no code behind at all: the .cs file is absent. As Caliburn.Micro injects the InitializeComponent() call you don 't need that file at all. You can't write code behind by mistake if there is no file to do it.

    Another nice feature I found in Caliburn.Micro is the implementation of the Screen Activator pattern. You shoudn't open and close views at your will and catch the "isn't saved" issue sometimes and miss it some other times. The “Screen Activator” Pattern is explained by Jeremy Miller. I won't explain it here but it's important to emphasize that it fits the general view separation pattern (MVC, MVP, MVVM).

    Recently I was asked to develop something in WindowsForms. It started life as usual WindowsForms projects: event handlers, more event handlers and even more event handlers. It  became obvious something was missing: screen activator pattern for starters and while we are at it, MVVM for WinForms.

    I asked Google about it and got no obvious results. I asked two of my techies co-workers if MVVM for WindowsForms was possible. Both gave me the exact same answer: "No way! WindowsForms is missing the rich bindings of WPF and Silverlight (OneTime, OneWay, TwoWay, OnewayToSource) and it is also missing the TypeConverters."

    First things first.

    • Screen Activator Pattern for WindowsForms - you can find it here, ported by jagui
    • Rich Bindings and TypeConverters - Truss by Kent Boogaart, does it in an UI independent way
    • Commands - WPF Application Framework (WAF) has a WafWinFormsAdapter project that takes care of some MVVM stuff namely commands


    Again, can we have MVVM for WinForms?

    Yes we can. We have all the pieces. We just have to glue them together.

    Can we port Caliburn.Micro to WindowsForms?

    Not yet. Several problems have to be solved first. Remove four references from Caliburn.Micro and you'll see what I mean:
    - WindowsBase
    - PresentationCore
    - PresentationFramework
    - System.Windows.Interactivity


    The are four bigs issues identified so far:
    1. Get rid of DependencyObject and DependencyProperty that pops a bit everywhere in CM
    2. Replace FrameworkElement and UIElement by WindowsForms objects
    3. Stick to WAF's implementation of Command or replace EventTrigger
    4. Replace DataContext

    There are also a lot of small issues that I hope can be solved easily. I'll report back.