Archive for December, 2007

The Class Designer in Visual Studio: close to useless?

I really like the idea of having an embedded Class Designer in Visual Studio. It’s unfortunate that I can’t really use it effectively, though. I’ve been trying to use it every since it came out, but I often end up either going to Visio or just going to the whiteboard and drawing sketches manually.

There are just a few things I like about the VS Class Designer:

  • It looks fancy;
  • I don’t have to go anywhere else for a diagram.

That’s it.

As far as creating classes and its members, I think it’s much more productive to just do that in code (which is a lot faster if you’re using a tool such as CodeRush). So I really don’t see myself using the class diagram when I’m creating this stuff. If I’m trying to design something, I’ll just do it directly in a TDD style, or go to a whiteboard and sketch the simplest diagram I need in order to better understand what tests I need to write for my design.

There are more things I don’t like about the VS Class Designer:

  • Even though some people like the idea that the diagram gets updated from source code, I’m not sure that’s a good thing. Most often than not, I create diagrams that are as simple as possible, where I only include as many details needed to make the intent of the design as clear as possible. That means I carefully choose what members of a class I want to display.

    That said, I don’t want to add a property to a class in code and have it automatically added to the diagram (I may have added the property for implementation details and don’t want that cluttering the diagram). If it takes a lot of time from me to lay out a diagram, I may not want to add a property to a class and take the risk of that change messing up the layout of my pretty diagram. Well, that sucks (I want to make changes freely, and only change the diagram if I feel that the change is necessary to better explain the design).

  • Even though not directly related to the Class Diagram, I don’t like the fact that there’s no Sequence Diagram and State Diagram designers (two of the diagrams that are really helpful in explaining designs). I do understand that the diagrams in VS are not UML diagrams, but they do have lots of similarities, and it’d be good to have something like Sequence and State diagrams available.

Now to the thing that I hate the most about it:

  • There is no easy way to represent class relationships other than inheritance.

    Granted, inheritance is one of the pillars of OOP and must definitely be used wherever it makes sense. However, there are other things that may be deemed more appropriate to certain designs, such as the OOD principle "favor composition over inheritance". There’s just no way to represent composition in a way that makes sense. There’s a Power Tool for VS that adds a little support for composition, but that doesn’t work for me. If you add a composition relationship between two classes, the tool adds the arrow to the diagram pointing the two classes, but doesn’t show the reference as a property on the containing class. When you do that, it also adds code to your class that you may not want. For instance, if I have a class that has a property of a type that’s another class sitting there on the same diagram, the tool isn’t smart enough to draw the arrow for you, and if you try it yourself, it’ll add another property to hold the reference. Ouch.

     Diagram

  • There’s also no way to indicate that "this class uses that other class". One can add a "comment" to the diagram, but can’t really link it to any element on the diagram.

To overcome these problems I end up creating a part of the diagram in VS, and then using a tool such as MSPaint or Paint.NET to draw the other visual elements. What a shame.

Those are real deal breakers for me. Like I said, I keep trying to use the VS Class Diagram, but it’s been frustrating.  Diagrams are useful in some areas, but I certainly don’t want to become a slave for them, and when I do want to create a diagram, I want it to be ease to create and understand, and the current tool does not really give me that.

Advertisements

3 Comments

SnagIt integration with Team System

I’ve posted before regarding SnagIt being my tool of choice for screen capture.

I’ve found out recently about this add-on for SnagIt that allows the output of the screen capture to go directly to a work item (new or existing one) in Team Foundation Server (TFS). This is neat. Excellent for attaching screenshots to better illustrate bugs, requirements, etc. The add-on can be downloaded here: http://www.techsmith.com/snagit/accessories/teamsystem.asp

At first it didn’t work for me. It turns out that there’s a bug on the add-on that prevents it from working in cases where you’re connecting to multiple TFS boxes (my case). Their customer support pointed me out to a workaround, which solves the problem.

Leave a comment

IsDirty, synchronization, etc.

Not too long ago I posted something regaring DataBinding, DevExpress controls, synchronization of RibbonControl, etc.

Today I just ran across this article, which is sort of related to one of the things I mentioned regarding my original issue. I want to keep that article in mind for whenever I’m back working in that area, since I may want to refactor it into something that uses the approach described in the article.

Leave a comment

Windows Vista User Experience Guidelines

I just ran across this document:

Preliminary draft of the Windows Vista™ User Experience Guidelines (UX Guide)

Definitely useful for those designing user interfaces that should follow the Windows Vista standards.

Leave a comment

A simple approach for handling shortcuts in an application

The other day I was messing with making an application be configurable to have shortcuts for specific functions. For instance, in a data-entry form that has the typical functionality such as "new", "load" (or "open"), "save", etc., which are triggered by a click on a button somewhere (right on a form or on a Toolbox or Ribbon control), the users also expect to be able to use keyboard shortcuts (such as Ctrl+N for "new" and Ctrl+S for "save") so to trigger those common features.

I knew that it could be done by handling events such as KeyPress or KeyDown directly on a form, but I wanted to write a more generic and reusable solution (which is part of another thing that I’m working on, but I’ll leave that for another post).

In this post I’m going to present a simplified version of the design and implementation for the solution I’m going with (I’m stripping out some details and making a few changes to make it simpler, since eventually I’m going to come back to this and more more details).

What is the requirement?

When a data-entry form is active, the user wants to press Ctrl+N to create "new" data, Ctrl+O to "load" existing data, and Ctrl+S to save data. Since the purpose of this post is not to show how to right data access layers, business objects, etc., those shortcuts will simply trigger the display of a MessageBox stating what operation should be executed at that point.

Another requirement is that those shortcuts should be enabled or disabled depending on some logic; for instance, "save" should be disabled if no data has changed, and maybe "new" should be disabled if the user doesn’t have rights to create new data on that form. For this post, I just show how the options can be enabled/disabled (the actual logic to decide when to enable/disable a feature is beyond the scope of this post).

The usage

As I mentioned, I wanted to encapsulate that functionality somehow so that it can be easily maintained and reused. I have then created a "SimpleDataInterfaceShortcutHandler" class for that (from here on I’ll refer to this class as the handler class for the sake of brevity). The way to use it (at least for the scope of this post) is to instantiate the class somewhere in a form (such as in its constructor), passing the a reference to the form into the class (since it uses the form’s capabilities to detect the key that was pressed), and then setting properties to determine what shortcuts should be enabled. Something like this:

SimpleDataInterfaceShortcutHandler shortcutHandler = 
new SimpleDataInterfaceShortcutHandler(this); shortcutHandler.LoadEnabled = true; shortcutHandler.NewEnabled = true; shortcutHandler.SaveEnabled = true;

The shortcut key combinations

There’s a Keys enum within the System.Windows.Forms namespace. This enum lists values for all the keys in a keyboard. I’ve added three constants to my handler class so to store the values for my shortcut key combinations: one constant for each shortcut that I want to support:

/// <summary>
/// The shortcut that triggers the "NEW" functionality.
/// </summary>
private const Keys NEW_Shortcut = Keys.Control | Keys.N;

/// <summary>
/// The shortcut that triggers the "LOAD" functionality.
/// </summary>
private const Keys LOAD_Shortcut = Keys.Control | Keys.O;

/// <summary>
/// The shortcut that triggers the "SAVE" functionality.
/// </summary>
private const Keys SAVE_Shortcut = Keys.Control | Keys.S;

Executing actions associated with the shortcuts, and the Command pattern

In order to execute actions associated with a given shortcut, I decided to use a simplified version of the Command pattern, by using a delegate that I named ExecuteShortcut:

/// <summary>
/// Represents the method to be executed when a shortcut is triggered.
/// </summary>
private delegate void ExecuteShortcut();

Storing the shortcut bindings and the actions that they execute

In order to set the shortcut bindings and the actions that they’re supposed to execute, I use a Dictionary<Key, Value> collection. For the key I use the keyboard combination (which I’ve defined as a set of constants), and for the value I use an instance of the ExecuteShortcut delegate, which holds a reference to the command to be executed when the shortcut is triggered. This is the definition of my field that stores such collection:

/// <summary>
/// Dictionary of shortcuts controller by the handler. 
/// The key for the dictionary is the "key" combination that the shortcut is mapped to,
/// whereas the value is a delegate that points to the action to be executed when the 
/// shortcut has been triggered.
/// </summary>
private Dictionary<Keys, ExecuteShortcut> m_Shortcuts = 
new Dictionary<Keys, ExecuteShortcut>();

Registering the shortcuts and actions

In order to register the shortcuts and their actions, I’ve decided to provide special methods for that, as opposed to going straight to the m_Shortcuts dictionary. That way, if I ever decide to store the bindings in a different way, I can do that easily without breaking anything. The RegisterShortcut and UnregisterShortcut methods look like the following:

/// <summary>
/// Registers a shortcut and it's related action with this handler.
/// </summary>
/// <param name="shortcut">The shortcut.</param>
/// <param name="shortcutAction">The shortcut action.</param>
private void RegisterShortcut(Keys shortcut, ExecuteShortcut shortcutAction)
{
    if (!m_Shortcuts.ContainsKey(shortcut))
    {
        m_Shortcuts.Add(shortcut, shortcutAction);
    }
}

/// <summary>
/// Unregisters the shortcut from this handler.
/// </summary>
/// <param name="shortcut">The shortcut.</param>
private void UnregisterShortcut(Keys shortcut)
{
    m_Shortcuts.Remove(shortcut);
}

Nothing special there. The only thing is that the RegisterShortcut only adds a new binding to the dictionary in case it does not already exist there.

Enabling and Disabling shortcuts

Enabling and disabling shortcuts is a matter of registering and unregistering the specific bindings. We do that in the setter method of each "Enabled" property, like so:

/// <summary>
/// Gets or sets a value indicating whether the New functionality is enabled.
/// </summary>
/// <value><c>true</c> if [new enabled]; otherwise, <c>false</c>.</value>
public bool NewEnabled
{
    get
    {
        return this.m_Shortcuts.ContainsKey(NEW_Shortcut);
    }
    set
    {
        if (value == true)
        {
            this.RegisterShortcut(NEW_Shortcut,
                delegate()
                {
                    MessageBox.Show("Should be creating a new something...");
                });
        }
        else
        {
            this.UnregisterShortcut(NEW_Shortcut);
        }
    }
}

/// <summary>
/// Gets or sets a value indicating whether the Load functionality is enabled.
/// </summary>
/// <value><c>true</c> if [load enabled]; otherwise, <c>false</c>.</value>
public bool LoadEnabled
{
    get
    {
        return this.m_Shortcuts.ContainsKey(LOAD_Shortcut);
    }
    set
    {
        if (value == true)
        {
            this.RegisterShortcut(LOAD_Shortcut,
                delegate()
                {
                    MessageBox.Show("Should be loading something...");
                });
        }
        else
        {
            this.UnregisterShortcut(LOAD_Shortcut);
        }
    }
}

/// <summary>
/// Gets or sets a value indicating whether the Save functionality is enabled.
/// </summary>
/// <value><c>true</c> if [save enabled]; otherwise, <c>false</c>.</value>
public bool SaveEnabled
{
    get
    {
        return this.m_Shortcuts.ContainsKey(SAVE_Shortcut);
    }
    set
    {
        if (value == true)
        {
            this.RegisterShortcut(SAVE_Shortcut,
                delegate()
                {
                    MessageBox.Show("Should be saving something...");
                });
        }
        else
        {
            this.UnregisterShortcut(SAVE_Shortcut);
        }
    }
}

The two important pieces are the constant that we pass to the RegisterShortcut method, indicating which shortcut we’re registering, and also the delegate with the command to be executed whenever the shortcut is triggered. This is where the Command pattern is being used: the action is not being executed just yet; we’re only registering the command to be executed when necessary. Also, in this sample, I’m using an anonymous method, since the code to be executed is just a one-liner. I figured the code is clean enough if written like that, since it’s easy to see what shortcut is being registered, and what action is going to be triggered by it.

Hooking up the handler and the form

As I mentioned before, I use the form’s capabilities to trap what keys have been pressed. When the handler gets instantiated, we hook things up in the class’s constructor, like so:

/// <summary>
/// Initializes a new instance of the <see cref="DataInterfaceKeyboardHandler"/> class.
/// </summary>
/// <param name="form">The form.</param>
public SimpleDataInterfaceShortcutHandler(Form form)
{
// Causes the form to receive the key stroke
// even when a control is currently selected on it.
form.KeyPreview = true;


// Only KeyUp seems to trap all keys, including function keys (F1, F2, etc.)
form.KeyUp += new KeyEventHandler(form_KeyUp); }

As the inline comments say, the form’s KeyPreview is property is set to true so to cause the form to receive a key even if the focus is on a control contained in the form (such as a TextBox). Also, KeyUp is the event that I subscribe to in the form. That seems to be the only event that receives all the keys and combinations that I’m interested on. For some reason, the other events such as KeyPress and KeyDown don’t receive keys such as F1, F2, F3, etc, and some combinations such as Ctrl+Key.

Finally, this is the event handler for the KeyUp event:

/// <summary>
/// Handles the KeyUp event of the form control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> 
/// instance containing the event data.</param>
void form_KeyUp(object sender, KeyEventArgs e) { if (this.m_Shortcuts.ContainsKey(e.Modifiers | e.KeyCode)) { ExecuteShortcut action = this.m_Shortcuts[e.Modifiers | e.KeyCode]; action(); } }

This is how that method works:

  1. We first check to see whether the key combination (Modifier, such as "control" or "shift", plus the KeyCode, such as "N", or "S") is registered as a shortcut. In such case we know we have an action to execute;
  2. We retrieve the command object (that is, the delegate associated with the shortcut) from the dictionary;
  3. We execute the delegate.

Summing up

That’s it. This simple class can now be used wherever needed, but most importantly, it’s easy to refactor it into something that can be a lot more powerful.

For instance, it could have a different way to hook up to the "keystroke trapping" (maybe there’s a better way then how I did it here, and maybe there’s a different way of doing it in another scenario, such as in WPF); if that’s the case, it’d be easy invert things here and remove the small dependency that the handler has on the Form class.

Also, in this simple example we have the handler having knowledge of what actions to execute; on the actual scenario where I’m implementing this class, instead of the handler itself having the action to be executed, it actually delegates the execution to a controller class, which can be swapped on the fly depending on the context where the shortcut was fired.

Finally, another thing that I like about this solution is that we don’t have just a single event handler on the KeyUp event, with a big and nasty switch statement on the key combinations and the actions all implemented mixed up into a single method.

Download source code

2 Comments

Xml Comments, GhostDoc, Documentor…

Here at EPS we’ve been getting more and more serious about the use of XML comments. Users of our framework always appreciate when we have good XML comments and always ask us to keep improving on it, so as much as possible we’re going back to legacy code and improving comments, as well as trying to write good comments for any new code we write.

Fortunately, there are tools to help us improve the quality of our XML comments. I’m listing here some of the ones we’ve been using.

Visual Studio

The code editor supports adding XML comments by typing /// (or ”’ in VB) right by the Type or member you want to put comments on. We can then set a property on the project (on the Build tab) to specify that an XML file has to be created with all the XML comments content upon every build. By default that option is unchecked.

XmlPropConfig 

We use different build configurations here, so we only turn that option on in our "Check-in Build", which is our most restrictive build. That option is off in all other builds because we want the local build process to be as quick as possible (if we’re in TDD-mode, we don’t want the compiler busy generating XML documentation files unnecessarily…).

When "XML documentation file" is enabled on the current type of build configuration for the project, the compiler lists warnings for every public type or member that does not have XML comments on it. In our check-in build we enable "Treat Warnings as Errors", which prevents the developer from even building the binaries in case there are missing comments.

WarningsAsErrors

Unfortunately, the compiler does not check whether there is actually anything within the XML comment tags, so a developer could get around the compiler error with something like this:

EmptyComments

That leads me to the next session…

Custom Rules for FxCop and Code Analysis

In order to make sure "smarty-pants" developers are aren’t fooling the compiler just by putting in empty comments, we wrote a custom FXCop rule that traps that, so that such violation won’t go unnoticed.

Not only we want developers to put comments on public members, but we also want them to put comments on private members. While the comments on the public members are helpful for people using the APIs, the comments on the private members are helpful for people maintain the code within the APIs.

Since the compiler only catches missing XML on public members, we also made our custom FXCop rule check for comments on private members.

Of course, those rules are no good if the assembly is not set to create the XML documentation file, so we also use a rule that checks to make sure every assembly has the xml file. We borrowed the rule from this article.

Why document private members??

The other day I was going through some code I found on the web (some very good code, by the way. I’ll be writing another post about it soon), and ran across this notFiredResult field somewhere. The usage or reason of this field wasn’t entirely clear to me, and IntelliSense didn’t give me much:

NoIntelliSense[5]

I then pressed F12 (or Go to Definition), and got to the field’s declaration:

InvalidXmlComment

Ok, that tells me something that’s more useful. I just wrapped up the existing comment into an actual valid XML-style comment, like so:

ValidXmlComment

And now I get that directly in IntelliSense:

GoodIntellisense

That’s such a simple change, but the removal of friction helps a lot when working on the code (the less I have to jump around the quicker it is for me to get the job done).

GhostDoc

This is one of the best free add-ins for Visual Studio: GhostDoc. This is a must-have tool to our developers here. 

GhostDoc does a pretty good job at creating initial XML comments. However, developers should ALWAYS make sure to verify what GhostDoc created, and edit it accordingly. For instance, if a method is named "MyMethod", GhostDoc creates documentation that say "Mies the method." (of course nobody should name a method like that anyways, but the point is that there are cases where GhostDoc can’t quite figure out the best way to write the comments, so the developer should always do some proof-reading).

Also, one feature I love bout GhostDoc is that it "inherits" XML comments from baseclasses and interfaces (when available). Say you override a method from a baseclass in .NET; you don’t have to type in the comment yourself, since GhostDoc will just grab the comments from the baseclass and paste it into your code.

Documentor

CR_Documentor is another plug-in for Visual Studio that rocks! When the Documentor window is being shown, it displays a preview of what the MSDN-like type of documentation will look like once you turn XML documentation into and more human-readable documentation. This helps a lot when typing the XML comments, since the developer can immediately see what the output is going to look like.

Even if you’re not planning to create the MSDN-like documentation out of your source code, the tool is also useful to improve the visualization of the XML comments within VS; a formatted HTML page is much easier to read then green comments in XML tags. Whenever I’m working with some code that I’m trying to learn about it, I have the Documentor window docked somewhere in VS:

Documentor1

Also make sure to check what’s available when you right-click on an XML comment once you get Documentor installed. There’s a bunch of little things that helps a lot composing decent documentation (such as options to add bulleted lists, sample source code, etc.):

Documentor

1 Comment

More custom embedding using CodeRush

I’ve just read Mark Miller’s post regarding this other great post on how to create custom embedding using CodeRush. I had actually done that before, but had not hooked it up to shortcuts. That’s extremely easy, useful, and fun!

That got me to go back and improve my custom embedding that wraps up a selection into either an if-block or else-if block. I’ve customized it so that when I have some code selected in the editor, I can hit either i (as in if) or e (as in else), which causes the code to be wrapped in an if or if-else block, respectively:

if[7] 

if[5]

Below is what my custom if-else embedding looks like (you can figure out the if one…):

embbed

And this is what the shortcut look like:

shortcut

Leave a comment