Almost two months ago I talked about how to do application prototyping using the Pencil Project. However in the last couple of weeks I’ve tried out Balsamiq Mockups and I have to say that I’m very impressed.

Although being a non free solution the added value provided by Balsamiq Mockups more than compensates the initial cost. The feature that I think tips the scale for Balsamiq is that the process of creating a mockup is very simple and streamlined (The Quick Add works very well).

Last but not the least the simple hand-drawn look of the mockups is pretty cool and also transmits the right idea… “This is just a mockup people, criticize at will!”

A search mechanism is something unavoidable for most applications. A common scenario is to provide the user a set of filters for which he can supply values and incrementally restrict the number of records that satisfy these restrictions.

Search Form

It’s also normal for the user not to use all the filters supported by the search form which means that the unused filters must be excluded from the search query to not affect the result. A quick solution to this problem is to generate this search query dynamically and omit the empty filters.

However in this example I will be taking advantage of the fact that SQL Server supports expression short-circuiting to use an Entity Framework data source control with a static Where clause.

<asp:EntityDataSource ID="eds" runat="server"
    ConnectionString="name=EnContext" DefaultContainerName="EnContext"
    EntitySetName="ProductSet"
    Select="it.ID, it.Name, it.Type, it.Discontinued"
    AutoGenerateWhereClause="false"
    Where="(@NameFilterEmpty OR it.Name LIKE @NameFilter) AND (@TypeFilterEmpty OR it.Type = @TypeFilter) AND (@DiscontinuedFilterEmpty OR it.Discontinued = @DiscontinuedFilter)">
  <WhereParameters>
    <My:ControlFormatParameter Name="NameFilter" ControlID="nameTB"
      DbType="String" Format="%{0}%" />
    <My:EmptyControlCheckParameter Name="NameFilterEmpty"
      ControlID="nameTB" DbType="Boolean" />
    <asp:ControlParameter Name="TypeFilter" ControlID="typeDD"
      DbType="Int32" PropertyName="SelectedValue" />
    <My:EmptyControlCheckParameter Name="TypeFilterEmpty"
      ControlID="typeDD" DbType="Boolean"
      PropertyName="SelectedValue" EmptyValue="-1" />
    <asp:ControlParameter Name="DiscontinuedFilter"
      ControlID="discontinuedRBL" DbType="Boolean" />
    <My:EmptyControlCheckParameter Name="DiscontinuedFilterEmpty"
      ControlID="discontinuedRBL" DbType="Boolean" />
  </WhereParameters>
</asp:EntityDataSource>

As you see in the previous code snippet each search filter is controlled by a specific boolean parameter that when true disables the associated filter. The classes ControlFormatParameter and EmptyControlCheckParameter both derive from ASP .NET ControlParameter and allow in the first case to format the value of the associated input control before passing it to the data source and in the second case to switch each search filter on/off by evaluating if the associated input control has an empty value.

public class ControlFormatParameter : ControlParameter
{
    public string Format { get; set; }

    protected override object Evaluate(HttpContext context, Control control)
    {
        return String.Format(this.Format, base.Evaluate(context, control));
    }
}

public class EmptyControlCheckParameter : ControlParameter
{
    public EmptyControlCheckParameter()
    {
        this.EmptyValue = string.Empty;
    }

    public string EmptyValue { get; set; }

    protected override object Evaluate(HttpContext context, Control control)
    {
        string value = base.Evaluate(context, control).ToString();

        if (String.Equals(value, this.EmptyValue, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }

        return false;
    }
}

For the developers out there that sometimes like/have to pretend they are designers and need to create prototypes for graphical user interfaces the Pencil Project is an application to take in mind.

For starters, it’s free, unlike Microsoft SketchFlow or Balsamiq Mockups, which judging by the demo at their site seems pretty interesting but since I do some pretty basic stuff I don’t think it would pay off. Have to check their trial, though.

The Pencil Project runs as a standalone application or as a Firefox add-on. You can download it at the main site or directly from the evoluspencil code repository where you can also find more stencils packages.

Mockup Example using Pencil Project

Moles is a lightweight detour framework that lets you replace any .NET method (including static methods) with your own delegate.

The latest version of Microsoft Pex brought some very interesting improvements. Amongst them and the one that got me most curious was the support for using Moles with NUnit tests.

When writing unit tests is common to have tests with external dependencies not relevant to the behaviour under test. Using mocking frameworks you can get around these situations but the most popular ones like Rhino Mocks and Moq, as far as I know, cannot mock sealed types or static methods. Typemock however places no constraints but is not free.

With Moles you have greater flexibility and the delegate based approach is also easy to read and understand as you can see in the next example:

[Test]
[Description(
    @"An exception SHOULD be thrown if the default value
    is not valid for the associated option definition type."
    )]
public void Constructor_T008()
{
    MOptionType optionType = new MOptionType();

    optionType.NameGet = () => "OptionTypeMock";
    optionType.CanChangeDefaultValueGet = () => true;
    optionType.MinValuesCountGet = () => 1;
    optionType.MaxValuesCountGet = () => 1;
    optionType.ValidateValueObject = x => false;

    Assert.Throws<ArgumentException>(() => {
        new OptionDefinition(optionType, "Name", "NonBooleanValue");
    });
}

In the previous code snippet I configure a mole for an OptionType instance to return false in the method ValidateValue allowing me to test that the OptionDefinition constructor reacts in a proper way when the provided argument is an invalid value.

Since Moles needs the Pex profiler to work, you have to run this NUnit test using Pex command line runner with NUnit console.

Example:
pex /runner:D:\TOOLS\nunit-console.exe Parser.UnitTests.dll

Get Dynamic with C# 4.0

November 23, 2009

C# 4.0 is already around the corner and I haven’t even had time to wrap my head around LINQ, that stuff C# 3.0 was all about. (I really need to read a book or two about that, maybe I’ll include it as a new year resolution.)

Back to dynamic, today I finally installed VS 2010 Beta 2 with all the 4.0 goodies (C# and .NET Framework) and the first thing I had to try was, of course, the new dynamic keyword.

To do this I decided to revisit my Command Line Parser and add some dynamism to it. The goal would be to simplify it’s typical usage illustrated in the following code:

// Mandatory options
string dataFile = (string)cmdLine.Options["DataFile"].Value;
string schemaFile = (string)cmdLine.Options["SchemaFile"].Value;

// Flag and Switch options always have a value
bool verbose = (bool)cmdLine.Options["Verbose"].Value;
bool test = (bool)cmdLine.Options["UseTransaction"].Value;

// Check if the value for a non mandatory option is available
string connString;
if (cmdLine.Options["ConnectionString"].Available)
{
    connString = (string)cmdLine.Options["ConnectionString"].Value;
}

The above code would be a lot nicer if it weren’t for those casts and string literal references, so to remove them I implemented a new class inheriting from DynamicObject and added a method to the already existing OptionCollection class to return it wrapped inside the new dynamic object. Here’s the code:

public sealed class OptionCollection : Collection
{
    // ...

    public dynamic AsDynamic()
    {
        return new DynamicOptions(this);
    }
}

internal sealed class DynamicOptions : DynamicObject
{
    public DynamicOptions(OptionCollection options)
    {
        this.Options = options;
    }

    private OptionCollection Options { get; set; }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (this.Options.Contains(binder.Name))
        {
            result = this.Options[binder.Name];

            return true;
        }

        return base.TryGetMember(binder, out result);
    }
}

With this I can now access and use the command line options like this:

// Get the options as dynamic
dynamic options = cmdLine.Options.AsDynamic();

// Mandatory options
string dataFile = options.DataFile.Value;
string schemaFile = options.SchemaFile.Value;

// Flag and Switch options always have a value
bool verbose = options.Verbose.Value;
bool test = options.UseTransaction.Value;

// Check if the value for a non mandatory option is available
string connString;
if (options.ConnectionString.Available)
{
    connString = options.ConnectionString.Value;
}

Pretty sweet, no?

Developing for Microsoft Office with VSTO is fantastic, I mean, when the only other option is VBA. And that was basically the main reason I ended up working with VSTO in the first place.

A problem I had right in the beginning of my adventure was with the user interaction with the add-in. It was a simple custom toolbar with buttons, nothing fancy, but sometimes after using the add-in for a while the buttons would just randomly stop responding.

The bug was in the code that created the command bar and attached the event handlers. In order to configure and add the click event handler I was using a local variable to reference the newly added command bar button. Being local this variable would later be collected by the GC resulting in the loss of the event handler. So don’t forget… specify all command bar button variables at the add-in level to prevent them from being garbage collected.

You can check this behavior in the following example:

using System.Windows.Forms;
using Office = Microsoft.Office.Core;

public partial class ThisAddIn
{
    private Office.CommandBar bar;

    private Office.CommandBarButton showMsgCorrect;

    private void ThisAddIn_Startup(object sender, EventArgs e)
    {
        bar = Application.CommandBars.Add(
            "Example Bar",
            Office.MsoBarPosition.msoBarTop,
            false,
            true);

        // Do this
        showMsgCorrect = (Office.CommandBarButton)bar.Controls.Add(
            Office.MsoControlType.msoControlButton,
            missing,
            missing,
            missing,
            missing);

        showMsgCorrect.Caption = "It Works";
        showMsgCorrect.TooltipText = "Will always work";
        showMsgCorrect.Style = Office.MsoButtonStyle.msoButtonCaption;
        showMsgCorrect.Click += new Office._CommandBarButtonEvents_ClickEventHandler(button_Click);

        // Don't do this - Garbage collection will break it
        Office.CommandBarButton showMsgIncorrect;

        showMsgIncorrect = (Office.CommandBarButton)bar.Controls.Add(
            Office.MsoControlType.msoControlButton,
            missing,
            missing,
            missing,
            missing);

        showMsgIncorrect.Caption = "Will Stop Working";
        showMsgIncorrect.TooltipText = "Will stop working";
        showMsgIncorrect.Style = Office.MsoButtonStyle.msoButtonCaption;
        showMsgIncorrect.Click += new Office._CommandBarButtonEvents_ClickEventHandler(button_Click);

        bar.Visible = true;
    }

    private void ThisAddIn_Shutdown(object sender, EventArgs e)
    {
    }

    void button_Click(Office.CommandBarButton Ctrl, ref bool Cancel)
    {
        MessageBox.Show(
            "Hello World!",
            string.Empty,
            MessageBoxButtons.OK,
            MessageBoxIcon.Information);

        GC.Collect();
    }

    #region VSTO generated code

    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }

    #endregion
}

As you may have noticed I’m a command line type of guy, even more now thanks to Powershell, which by the way is now shipped with Windows 7 along with an integrated scripting environment (Powershell ISE). Take that for awesomeness…

Back to the topic. Was another options parser really needed? Probably not, but combine to much free time with wanting to do some more advanced stuff with regular expressions and also with the frequent development of command line utilities and you get this outcome.

I think the main advantage to other options parsing libraries is the in-depth knowledge I have of how it works. No advantage to you, I know, sorry about that.

Nonetheless, if you want to have a look, you can find the source code and binaries here (Command Line Parser). It supports the following syntax:

-v -useTransaction false -dataFile data.dat -schemaFile "My Schema.scm"

and here’s how to use it in your own applications.

static void Main(string[] args)
{
    string processName = Process.GetCurrentProcess().ProcessName;

    CommandLineParser parser = new CommandLineParser(processName);

    OptionDefinition definition;

    definition = parser.AcceptFlag("verbose", "v");
    definition.Description = "Runs the application in verbose mode.";

    definition = parser.ExpectSingle("datafile");
    definition.Description = "Specifies the data file.";

    definition = parser.ExpectSingle("schemafile");
    definition.Description = "Specifies the schema file.";

    definition = parser.AcceptSingle("connectionstring");
    definition.Description = "Specifies the connection string.";

    definition = parser.AcceptSwitch("useTransaction");
    definition.Description = "Specifies if a transaction is used.";
    definition.DefaultValue = true;

    ParsedCommandLine cmdLine;
    try
    {
        cmdLine = parser.Parse(args);
    }
    catch (InvalidCommandLineException parseError)
    {
        Console.WriteLine(parseError.Message);
        Console.WriteLine();
        Console.WriteLine(parser.UsageInfo);

        return;
    }

    // Mandatory options
    string dataFile = (string)cmdLine.Options["DataFile"].Value;
    string schemaFile = (string)cmdLine.Options["SchemaFile"].Value;

    // Flag and Switch options always have a value
    bool verbose = (bool)cmdLine.Options["Verbose"].Value;
    bool test = (bool)cmdLine.Options["UseTransaction"].Value;

    // Check if the value for a non mandatory option is available
    string connString;
    if (cmdLine.Options["ConnectionString"].Available)
    {
        connString = (string)cmdLine.Options["ConnectionString"].Value;
    }
    else
    {
        var main = ConfigurationManager.ConnectionStrings["Main"];

        connString = main.ConnectionString;
    }
}

Windows 7 – The Day After

November 4, 2009

To be honest it’s the day after the day after the day, but let’s not get lost in details. The main point is that I finally abandoned my old and trusted Windows XP for the new and shiny Windows 7.

Having stepped over Windows Vista I knew that this would be a big change but the reviews were good and I was really curious to try the new taskbar which by the way works very nicely. I have to say that I’m no fan of the Show Desktop button being on far right of the taskbar which could be a problem for me if it weren’t for the handy Win+D shortcut.

In terms of applications I haven’t had any compatibility problems although I changed my virtual drive software because with Windows XP I was using the free version of Alcohol 52% which triggered a warning in the Windows 7 upgrade advisor so now I’m using Slysoft Virtual CloneDrive.

The only thing that really annoyed me was the lack of a user interface to change the icon associated to a file type. Changing the default application for a given extension is easy, but if you want more control on the displayed icon you are out of luck. Thankfully you can download this awesome, at least to me, utility to quickly carry out this. Thumbs up to the creator of Types.

Sent from my Windows 7 computer…

Recently I had the need to validate that a given string contained only lower or upper case letters. In my first implementation I resorted to the following regular expression to do this validation: “^[a-zA-Z]+$”

I’m not a regular expressions advanced user but in this case I was pretty much convinced that it would work as expected. However when running the tests for that unit I got some unexpected results. The regular expression was allowing input of the form (“asd\n”) to pass the validation routine.

For this case I could just ignore the white-space by performing a String.Trim() on the input, but I got curious about the possibility to handle this situation using only a regular expression. With a bit of research I found out that instead of using the $ anchor I could replace it with the \z anchor that matches exactly the end of the string and not line breaks.

The following code illustrate this behavior.

var patterns = new string[] { "^[a-zA-Z]+$", @"\A[a-zA-Z]+\z" };

foreach (string pattern in patterns)
{
    Console.WriteLine("Pattern: {0}", pattern);
    Console.WriteLine();

    var inputs = new string[] { "abc", "abc\n" };

    foreach (string input in inputs)
    {
        Console.WriteLine("{0}: {1}", Regex.Escape(input), Regex.IsMatch(input, pattern));
    }

    Console.WriteLine();
    Console.WriteLine();
}

Earlier this year I had the need to do the initial data load for a new system. The data source was a highly complex and customized Excel spreadsheet that provided no way to easily automate the migration.

Manual processing it’s definitely not my cup of tea, so I decided that at least the result should be something much more manageable which immediately ruled out creating discrete SQL insert commands, given the hierarchical and highly relational nature of the data.

XML seemed like the way to go, but then I would need a custom application to interpret it and finally load it to the database. Fortunately Microsoft did just that with SQLXML, providing a very flexible way to load XML data into a relational database.

Being a console guy I ended up creating a quick console application that enabled me to more easily automate the process. The first version of this application contained almost all SQL XML configuration hardcoded, but recently I had some time and improved it with command line parameters for the available configuration. Try it here.