Thursday, March 12, 2015

Caliburn.Micro for Windows Forms and Visual WebGUI


On a post some 3 years ago, answering my own question "Can we port Caliburn.Micro to WindowsForms?", I said "Not yet. Several problems have to be solved first" and went on about all the issues to be solved. It turns out most problems were already solved by Dan Durland's port, that was hidden among the 100+ forks of Caliburn.Micro.

The port isn't complete and there are some issues, but overall, is a very good port.
  • One of the main issues was the lack of DependencyObject and DependencyProperty classes outside the WPF world. These classes are partially implemented, just enough the make the port easier to do.
  • Plain System.Windows.Forms events replace the functionality that is provided by the System.Windows.Interactivity Trigger stuff (EventTrigger and TriggerAction) used on regular Caliburn.Micro.
  • As ToolStripItem descend from System.ComponentModel.Component (and not from System.Windows.Forms.Control), a ToolStripItemProxy control is provided. The framework manages the life cycle of this control automatically, so you can ignore it altogether.
  • On the other hand, you can't ignore the provided ContentContainer control that replaces Panel. It knows about what ViewModel it is bound to, and is intended to host the UserControl that you want to load on your shell Form.
  • The message.attach feature is implemented as a string on the Tag property of the Button or whatever System.Windows.Forms.Control descendent you want.
If the latter feature implementation proves to be a problem (some people might use the Tag property for other purposes), the plan B is to implement this feature as a DependencyProperty.


The port doesn't support some very interesting Caliburn.Micro features, all in the Action parameters area:
  1. Support for SpecialValues parameters ($eventArgs, $dataContext, $source, $executionContext and $view)
  2. Support for $this parameters
  3. Support for object.property parameters
  4. Binding to object.property parameters
  5. Guard method re-evaluation on object.property change
Nonetheless, and repeating what I said before, I would say that overall, it is a very good port.

The MVVM FX project took Dan Durland's port as a working base and improved on it. All the issues outlined above were solved. Point 3 was solved with the help of MVVM FX own binding library, that is based on Truss by Kent Boogaart.

MvvmFx.CaliburnMicro went a step further and provides interesting features that are absent on regular Caliburn.Micro:
  • Support for $this.property parameters
  • Binding to $this.property parameters
  • Guard method re-evaluation on $this.property change
There is a feature that might prove interesting and is hold back until proven necessary:
  • Support for SpecialValues.property parameters

The Visual WebGUI project follows quite closely the Windows Forms implementation, but addresses two major differences:
  • There is no such thing as a UIThread under WebGUI.
  • A VWG application starts by building a Form (no Program.cs file) while Windows Forms applications uses Caliburn.Micro to build the shell Form.
All the samples have two projects: Windows Forms and WebGUI. Both projects share the exact same ViewModel

While Dan Durland's port is based on Caliburn.Micro version 1.3.1, the MVVM FX source was updated to 1.5.2, including all post 1.5.2 fixes that were applied before the regular Caliburn.Micro was ported to BCL.

A final note to say that MvvmFx.CaliburnMicro is formally in beta stage, but is stable enough for you to start developing with it. As soon as the samples are ready, it will be release, both on Codeplex and on NugGet, both for Windows Forms and Visual WebGUI.

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.

    Saturday, August 20, 2011

    VS 2010 Setup Project - how to upgrade?


    Setup projects under VS2005 and VS2008 were easy to upgrade:
    1. select the Setup project
    2. go to the Properties tab
    3. update the Setup project Version
    4. accept VS suggestion to change the Product Code
    5. build the Setup project
    This isn't enough under VS2010.
    Is it a bug? In fact no. It happens that VS2010 uses the installer in a smarter way. The MSI generated by VS2010 only replaces changed assemblies. The same principle is used by ClickOnce and it makes upgrades faster.

    The question is: what is a changed assembly? Different update date? Different size? Not at all. Assemblies are different when they have a different File Version. As simple as that.
    I'm not sure ClickOnce uses this criteria to identify different assemblies.

    Upgrading a Setup project under VS2010 is a bit more complicated:
    1. update the File Version of all assemblies that are changed for this upgrade
    2. generate new binaries for these assemblies
    3. select the Setup project
    4. go to the Properties tab
    5. update the Setup project Version
    6. accept VS suggestion to change the Product Code
    7. build the Setup project
    To know more about this subject and understand why you need to do it this way under VS2010, you can read an interesting discussion.

    So what about the SolutionInfo and the Consistent Version Numbers Across All Assemblies technique? It's a way to make sure you don't forget to update the File Version of all assemblies, even if they didn't change. It's a kind'a "fail safe" upgrade. Of course you risk to replace too many assemblies that in fact didn't need to be replaced. The choice is yours.