in
Forums
Blogs
DevExpress.com
Client Center
Support Center
DevExpress Channel

Mark Miller

  • CodeRush Xpress for C# and Visual Basic inside Visual Studio 2008

    Download CodeRush Xpress - free from Dev Express!

    CodeRush Xpress is a powerful developer productivity tool from Dev Express. The product is free, licensed by Microsoft on behalf of all developers working in Visual Studio 2008 in all paid-for product skus (e.g., Standard, Professional, Team System). Note however that CodeRush Xpress will not load in the Express Editions of Visual Studio.

    CodeRush Xpress includes features that support common developer tasks in the following areas:

    FeatureSummary

    CodeRush Xpress fully supports all language features of Visual Basic and C# in Visual Studio 2008. If a specific feature applies to only one of these two languages, it will be noted with one of these icons:

    VB     C#  

    More details on CodeRush Xpress functionality follow.

    NavigateFeatures

    Navigate

    CodeRush Xpress includes seven powerful navigation features to make getting to that important location fast and easy.

    Camel Case Navigation

    You can move among the lowercase-to-uppercase transitions using Camel Case Nav.

    To move right, hold down the Alt key and press the Right arrow key inside a camel case identifier.

    CamelCaseRight

    To move left, hold down the Alt key and press the Left arrow key inside a camel case identifier.

    CamelCaseLeft

    Camel Case Nav is useful when you want to rename an identifier and change the name in a manner that keeps a portion of the existing camel case identifier. For example, if an existing identifier was called "StartTasks" and you wanted to rename it to "StartFilteredTasks", you could use Camel Case Nav to instantly get the caret between the "Start" and "Tasks" parts before typing in the new part.

    Collect Marker

    Whenever a CodeRush Xpress feature takes you to a new place in the code, CodeRush Xpress drops a stack-based marker at the original location. You can return to the original location (collecting the marker and popping it off the stack) by pressing Escape (when no other tool tip windows or context menus are active).

    CollectingMarkers

    When you press Escape, CodeRush Xpress animates a small locator beacon around the marker. This locator beacon is useful when your eyes are looking elsewhere on the screen, especially if you work with a large monitor. CodeRush Xpress also attempts to shift the code vertically so its position is roughly equivalent to what it was when you last viewed it.

    Structural Highlighting

    Structural Highlighting helps you visually navigate the structure of the code. Matching delimiters are connected with low-contrast lines that are easy to read when this information is useful, and easy to ignore when your mind is on the code.

    Structural Highlighting

    Structural Highlighting is useful for understanding the flow of large methods or third-party C# code using a different leading brace position than you might otherwise work with.

    Tab to Next Reference

    You can quickly jump to the active identifier's next reference in the solution file by pressing the Tab key (as long as the caret is somewhere inside the identifier). All matching references (and declaration) to this identifier will be underlined and the selection will move to the next reference. Continuing to press the Tab key will cycle through all identifiers in the solution. Shift+Tab brings you back. You can also press Escape to return to the starting location (where the Tab to Next Reference feature was first invoked on this identifier).

    TabToNextReference

    Tab to Next Reference is useful when you want to quickly visit all references to a particular identifier or type.

    Highlight All References

    Highlight All References is visually similar to Tab to Next Reference, however it does not move the caret. Just press Ctrl+Alt+U to see all references to the active identifier.

    HighlightAllReferences

    Quick Navigation

    Quickly find a member, class, field or variable using Quick Nav. Just press Ctrl+Shift+Q to bring up the Quick Navigation window.

    You can filter the list by entering a portion of the identifier text you are looking for. If you hold down the Shift key and enter uppercase letters, you can find all identifiers named with those uppercase letters, as in the example below:

    Quick Navigation - Smart Filtering

    You can preview the target location by holding down the Ctrl key. To jump to the selected symbol, press Enter. To return to the starting location, press Escape.

    Quick File Navigation

    Quickly find and open any file in your solution. Just press Ctrl+Alt+F to bring up the Quick File Navigation window. The filtering mechanism in this window is similar to what we've just seen in the Quick Navigation window. Just enter a few letters from the file name. CodeRush Xpress will filter down the list. Use the Up and Down arrow keys to select the file you want to jump to, and press Enter to go there (or Escape to close the Quick File Navigation window and return to where you were).

    QuickFileNavigation

    SelectFeatures

    Select

    CodeRush Xpress includes five intelligent features for selecting code more efficiently.

    Camel Case Select

    If you need to select one or more words from inside a camel-case identifier, just use the Shift key along with the Camel Case Nav keys.

    For example, to select from the caret to the start of the camel case part to the left, use Alt+Shift+Left.

    CamelCaseSelect

    Selection Increase

    First, there is a command to increase the selection by logical blocks. For example, if the caret is inside an expression, you can quickly expand the selection so it entirely holds the expression. Being able to quickly define a selection around a logical block is useful for refactoring. You can also use it to quickly select code you want to move to another location. This command is bound to a shortcut: Alt+Shift+=.

    Selection Reduce

    If you accidentally overshoot the block you want to select, you can reduce the selection by logical blocks using Alt+Shift+-.

    Intelligent Cut, Intelligent Copy, and Paste Replace

    If you need to cut or copy an identifier to the clipboard, there's no need to select it with CodeRush Xpress. Just place the caret on the identifier and press the cut or copy key (e.g., Ctrl+X, Shift+Delete, Ctrl+C, or Ctrl+Insert). CodeRush Xpress will select the identifier before the cut or copy operation.

    Once you have an identifier on the clipboard, you can move the caret to a different identifier and replace it with the one on the clipboard using Ctrl+B. This Paste Replace command will select the identifier at the caret before pasting in the contents of the clipboard.

    If you need to cut or copy a larger structure, such as a for loop, a try/finally block, a member or a class, just place the caret at the start of the block you want to copy and press the cut or copy key. CodeRush Xpress will select the entire block before cutting or copying the block to the clipboard.

    DeclareFeatures

    Declare

    CodeRush Xpress includes powerful features to intelligently declare classes, members, fields, local variables and so much more.

    Consume-first Declaration

    The consume-first declaration features of CodeRush Xpress are a quick way to generate the code you need. It starts with a call or a reference to something that doesn't exist yet (the consumption code). Just move the caret to the reference that needs to be declared and press the CodeRush key (Ctrl+` by default). CodeRush Xpress will do the rest, declaring the missing member, type, enum, or variable.

    Consume-first declaration is useful because it gets you thinking in terms of developers who would consume the code you write. This can improve the quality of the code and make it easier for developers to work with your code. Consume-first declaration is also almost always an essential component of Test Driven Development (TDD).

    However one of the most significant benefits of consume-first declaration is the efficiency gain -- you can quickly craft the code you need significantly faster than doing the same by hand.

    To illustrate, let's look at a practical example. Often developers will use Intellisense to discover the return type of an unfamiliar method call or property, by entering that expression right inside the code, like this:

    UsingIntellisenseToGetReturnType

    Typically what happens next is the developer's eyes move to the front of the tool tip and note the type (circled in red above). Then the developer accepts the suggestion and moves the caret to the beginning of the line to enter a variable declaration of the correct type (e.g., a variable of type "Module[]" in this example).

    Overall there's a great deal of caret movement and typing involved just to declare a variable. To save a little time, some developers avoid specifying the type to implicitly declare variables (using the var keyword in C#, for example), thus avoiding the discovery and text entry costs associated with explicit declaration.

    Fortunately, CodeRush Xpress makes it easy to explicitly declare variables in a way that exploits the power of Visual Studio's Intellisense and is likely to be highly compatible with how you already work:

    1. Create the expression fragment on an empty line using Intellisense or simply typing the expression by hand.

      TypeExpression 

      CSharpSmall If you're working in C#, there is no need to end the expression with a semi-colon.
    2. With the caret at the end of the line, press the CodeRush key (Ctrl+`) and select "Declare Local" from the menu. CodeRush Xpress will generate the local variable declaration and select the variable so you can give it a meaningful name:

      DeclaredLocal 

    So the steps behind exploiting consume-first features are:

    1. Write the call or reference to the member, type or variable that doesn't exist, OR enter an expression on an empty line (as in the example above).
    2. Place the caret on the part that doesn't exist.
    3. Press the CodeRush key (Ctrl+`). If a menu appears select the item you want to declare. For methods and properties, you may also see a horizontal red line appear (called the Target Picker) that allows you to select the insertion point for that member. Just use the up and down arrow keys to select the ideal location and press Enter to insert the declaration.
    4. Sometimes CodeRush Xpress will shift the view or take you to another file, to show you the code just inserted. This allows you to rename or edit the newly-declared code. When you're satisfied with the declaration you can press Escape to collect the marker and return to where you started.

    More details on specific consume-first declaration features follow:

    Declaring Members

    Want to add a member to a type? Just write the code as you would like it to appear. If it's a method, pass in the parameters you need (tip: if you're passing in parameters that are undeclared, declare those first before declaring the method). Place the caret on the member and press the CodeRush key.

    Here are the consume-first member declarations you get with CodeRush Xpress:

    • Declare Constructor
    • Declare Method
    • Declare Property
    • Declare Property (auto-implemented)
    • Declare Property (with backing field)
    • Declare Getter
    • Declare Setter
    • Declare Event Handler

    Declaring Types

    To declare a new type, add a reference to it. Usually when you want a new type, you also want a constructor for it. So it's usually most efficient to enter the constructor call like on an empty line:

    NewTypeExpression

    At this point you can press the CodeRush key (Ctrl+`) to declare a new local variable as we've seen before. You can also place the caret on the "FileLogger" text and press the CodeRush key to declare a class or struct.

    Here are the consume-first type declarations you get with CodeRush Xpress:

    • Declare Class
    • Declare Delegate
    • Declare Enum
    • Declare Enum Element
    • Declare Interface
    • Declare Struct

    Declaring Variables

    As we've already seen, declaring variables to represent an expression on a line is easy. Another way to declare variables is to simply place the caret on a reference to the variable name in an assignment, as in the "_StartTime" text in the assignment below:

    FieldDeclaration

    Press the CodeRush key (Ctrl+`) and select the declaration you'd like. A preview hint will let you see the changes to the code before you commit.

    DeclareStartTime

    Here are the consume-first variable declarations you get with CodeRush Xpress:

    • Declare Field
    • Declare Local
    • Declare Local (implicit)

    Create Method Contract

    Often inside methods, before you work with the parameters, you need to verify that those parameters are valid. Developers typically select one of three mechanisms to ensure the data coming in is correct:

    • Throw an exception
    • Call Debug.AssertXxxx()
    • Exit the method

    Regardless of which one of these you prefer, CodeRush Xpress makes it easy to build this contract code. Just move the caret to the start of the method, like this:

     CreateMethodContract1

    Then press the CodeRush key (Ctrl+`). The Create Method Contract menu will appear, allowing you to select the ideal mechanism for validating any parameters that are without validation code.

    CreateMethodContract2

    The preview hint shows you exactly what you're going to get. Create Method Contract makes the process of ensuring parameters are valid fast and easy.

    Duplicate Line

    Duplicate line lets you create a new line of code based on an existing line of code. You can duplicate variable declarations, constants, and method calls. The shortcut is Shift+Enter. For example, if the caret is on a declaration like this in C#:

    DuplicateLine1

    Pressing Shift+Enter will create a duplicate declaration that looks like this:

    DuplicateLine2 

    Now it's simply a matter of typing in the new field name. Note that the Camel Case features , shown above, may be useful here if you want to change only a portion of the name (for example, changing _StartTime to _EndTime would be easy with Camel Case Nav and Camel Case Select).

    RefactorFeatures   

    Refactor

    Refactoring is a powerful way to improve the quality and flexibility of your code, without changing program behavior. Well-refactored code costs less to maintain, is easier to extend, and is a more valuable asset than code that is allowed to accumulate technical debt (also referred to as design debt).

    CodeRush Xpress includes over 50 refactorings, and nearly all work in both C# and Visual Basic. A few refactorings are available in only a single language due to features of that particular language.

    VBSmall  For example, Inline With Statement and Create With Statement are both available in Visual Basic.

    CSharpSmall Similarly, refactorings to Add Block Delimiters and Remove Block Delimiters are only available in C#.

    In some cases CodeRush Xpress provides wrappers for existing refactorings in either language. These wrappers ensure a more complete experience, making all refactorings contextually available in one location, accessed from a single keystroke (Ctrl+`). In many cases wrappers will also implement a preview hint, so you can see the impact of the changes before you commit. Wrappers are indicated in the refactoring menu with a Visual Studio icon, as in the Rename and Reorder Parameters refactorings appearing in the refactoring menu below:

      Wrappers

    In this section you'll find descriptions for all refactorings shipping inside CodeRush Xpress, arranged in the following categories:

    Changing Signatures
    Conditionals
    Declaration & Initialization
    Expressions
    Interfaces
    Lambda Expressions & Anonymous Methods
    Loops & Blocks
    Properties & Fields
    Moving/Extracting Methods
    Resource Files & Strings
    Types
    Visibility

    Consult the Visual Studio help after installing CodeRush Xpress for additional details and example code in both C# and Visual Basic demonstrating these refactorings in action.

    Changing Signatures

    Add Parameter

    Adds a new parameter to a method declaration and updates all calls accordingly.
      AddParameter

    Create Overload

    Creates an overloaded method similar to the one at the caret, with fewer parameters. Applying this refactoring leads to an interactive phase where you can select which parameters to exclude from the new overload. XML doc comments are updated appropriately. You can even create overloads of constructors, as shown in the screen shot below:
      CreateOverload

    Decompose Parameter

    Replaces a single parameter with one or more new parameters, each standing in for a property access on the original parameter. For example, consider the code below:

      DecomposeParameter0

    In the first constructor, only a single property of the parentGrid parameter, Children, is accessed inside the code (and aside from this property reference, parentGrid is never referenced or assigned to directly in the code). So we can replace this parameter with a parameter of the same type as the property referenced. The preview hint for Decompose Parameter shows the impact of this change:

      DecomposeParameter 
    After applying this refactoring, all calls to the method are updated. The final code looks like this:

      DecomposeParameter2

    Promote to Parameter

    Removes all references to the local declaration or field from the method, replacing it with a parameter. Calling code is adjusted to pass in the promoted field or expression.

    CSharpSmall
    In C#, CodeRush Xpress simply adds a preview hint wrapper around the existing refactoring.

    PromoteToParameter 
    VBSmall 
    In Visual Basic the refactoring is available as well, however in this case CodeRush Xpress actually implements the refactoring instead of handing off to the language service:

    PromoteToParameterVB

    Remove Unused Parameter

    Removes an unused parameter from a method declaration and updates all calls accordingly.

    VBSmall
    In Visual Basic this refactoring is only available on parameters that are not referenced within the method:

    RemoveUnusedParamter

    CSharpSmall
    In C# the Remove Unused Parameter refactoring is not available, however there is a wrapper for the built-in C# refactoring Remove Parameters, and that wrapper is available when the caret is on any parameter:

    RemoveParameters

    When you select the Remove Parameters, CodeRush Xpress calls the built-in C# refactoring, which allows you to select the parameters to remove:

    RemoveParametersBuiltInUI 
    Note: The image above is a dialog from Visual Studio and is not part of CodeRush Xpress.

    Reorder Parameters

    Reorders parameters in the current method, and then updates calling code to reflect the new order.

    CSharpSmall
    In C#, this refactoring hands control over to the existing C# implementation of Reorder Parameters:

    ReorderParametersCS
    Note: The image above is a dialog from Visual Studio and is not part of CodeRush Xpress.

    VBSmall
    In Visual Basic, the application of this refactoring leads to an interactive phase where parameters can be rearranged using the CodeRush Xpress in-source UI. A hint appears revealing available shortcuts in the interactive mode.

    ReorderParametersVB 

    Safe Rename

    Safely renames non-private methods and properties by creating a duplicate member to preserve the old signature, calling the renamed member from the old member. The old member is hidden from Intellisense and marked "Obsolete". References to the old member will generate compiler warnings directing developers to the new renamed member.

      SafeRename0
    After applying this refactoring, CodeRush Xpress selects and links the method name for an easy rename.

      SafeRename1

    Safe rename is useful if you want to change the signature of a public or protected method referenced by code outside of your solution (e.g., on a developer's machine in another part of the world making calls to your API). For example, after performing the Safe Rename on the code shown above, we can next apply Remove Parameter to the unused deprecatedData in the FindPlayers method, cleaning up its signature without breaking any code that calls the now-obsolete FindAllThePlayers method.

    Conditionals

    Combine Conditionals

    Combines nested conditionals to into a binary expression performing a logical AND operation. For example, "if (e1) if (e2)" becomes "if (e1 && e2)". This refactoring is the opposite of Split Conditional. This refactoring can also combine two or more neighboring conditionals with identical bodies into a single conditional statement where each conditional expression is logically OR’d.

    Here's an example where nested conditionals can be combined:

      CombineConditionalsAnd

    And here's an example where neighboring conditionals with identical bodies can be combined:

    CombineConditionals

    Combine conditionals will also remove any redundancy that might appear in the newly combined expression. For example, notice in the preview hint for the following how the reference to the hasQualified parameter appears only once:

      CombineConditionals2

    Compress to Ternary Expression

    Converts an if/else conditional with assignments in each branch into a ternary expression. This refactoring is the opposite of Expand Ternary Expression.

    CompressToTernaryExpression

    Expand Ternary Expression

    Converts a ternary expression into an if/else block. This refactoring is the opposite of Compress to Ternary Expression.

      Before:

      column = cellPosition == CellPosition.Last ? _NumColumns - 1 : 1;

      After:

      if (cellPosition == CellPosition.Last)
        column = _NumColumns - 1;
      else
        column = 1;

    Flatten Conditional

    Unindents all or a portion of the conditional statement. This refactoring applies one of the following refactorings: Replace Nested Conditional with Guard Clause, Remove Redundant Else, or Reverse Conditional followed by Remove Redundant Else. Flatten conditional can also recognize “if (E) return true; else return false;” and convert all of this to simply “return E;”.

    Here's one example for Flatten Conditional, where an indented code block (the last one of a method) becomes unindented by reversing the conditional and exiting the method:

    FlattenConditional

    Here's another example preview hint for Flatten Conditional, where an else keyword and the corresponding braces are removed, unindenting the contents of the block:


    FlattenConditional2

     

    Reverse Conditional

    Inverts the logic in this conditional statement and swaps the If and Else blocks.

    ReverseConditional

    Split Conditional

    Two behaviors:

    1. Converts a conditional with a binary expression performing a logical AND operation into nested conditionals. For example, in C#, "if (e1 && e2)" becomes "if (e1) if (e2)".

        Before:
         if (fileName != null && fileName != String.Empty)
           PlayInCell(fileName, column, row);


        After:
         if (fileName != null)
           if
      (fileName != String.Empty)
             PlayInCell(fileName, column, row);

    2. Converts a conditional with a binary expression performing a logical OR operation into neighboring conditionals.

        Before:
         if (fileName == null || fileName == String.Empty)
           return;


        After:
         if (fileName == null)
           return;
         if (fileName == String.Empty)
           return;

    Declaration & Initialization

    Convert to Initializer

    Converts a default constructor call immediately followed by object initialization into an object initializer.

      ConvertToInitializer

    Decompose Initializer

    Converts an object initializer to a default constructor call followed by object initialization. Available when the caret is on type reference in the constructor call.

      Before:
     
      MediaPlayerPro mediaPlayerPro = new MediaPlayerPro { NumColumns = 3, StartingFolder = @"C:\Images" };

      After:
     
    DecomposeInitializer

       Note the variable name is linked up after decomposing the initializer, allowing for a quick rename if desired.

    Make Explicit

    Converts an implicitly-typed local variable to a variable with an explicit type.

      MakeExplicit

    Make Explicit (and Name Anonymous Type)

    Converts an implicitly-typed local variable to a variable with an explicit type, creates a named type to represent the expression on the right, and replaces the anonymous type with a newly-declared type. Other anonymous types in this project having the same shape will also be replaced by the new type.

      MakeExplicitAndNameAnonymousType

    Make Implicit

    Converts an explicitly-typed variable declaration to an implicit one.

      MakeImplicit

    Move Declaration Near Reference

    Moves the declaration statement for a local variable near its first reference.

      MoveDeclarationNearReference
    This refactoring is sometimes useful in preparing a block of code for Extract Method (if a selected block contains the variable declaration, the variable won't need to be passed in as a input parameter).

    Move Initialization to Declaration

    Combines a local variable's declaration with its first initialization.
      MoveInitializationToDeclaration

    Name Anonymous Type

    Replaces the anonymous type with a newly-declared type.

      NameAnonymousType
    Additionally, other anonymous types in this project having the same shape (matching property names of the same types) will be replaced by the new type. For example, watch what happens when you apply this refactoring the first anonymous type assigned to the variable superCar1 below:

      Before:
      var superCar1 = new { MaxSpeed = 250, Driver = "Speed" };
      var superCar2 = new { MaxSpeed = 250, Driver = "Racer X" };

      After:
      var superCar1 = new SuperCar(250, "Speed");
      var superCar2 = new SuperCar(250, "Racer X");

    The anonymous type assigned to superCar2 is also replaced by the new type.

    Remove Assignments to Parameter

    Removes assignments to value parameters, declaring a new local at the first assignment.

      RemoveAssignmentsToParameter

    Split Initialization from Declaration

    Breaks an initialized declaration for a local variable into a declaration and a separate initialization statement.

      Before:
      string[] files = System.IO.Directory.GetFiles(_StartingFolder);

      After:
      string[] files;
      files = System.IO.Directory.GetFiles(_StartingFolder);

    Split Temporary Variable

    Splits a local variable which has too many assignments, declaring a new local at the first new assignment following the first reference. In this example where the local variable "i" has multiple assignments and references, the preview hint shows a new variable named "splitI" will be introduced, and all subsequent references to "i" will be replaced with the new splitI variable.

    SplitTemp 

    Expressions

    Inline Temp

    Replaces all references to a local variable with its initial value.

      InlineTemp2

    Introduce Constant

    Declares a new constant, initialized to the value of the string or number at the caret.
    IntroduceConstant

    Introduce Constant (local)

    Declares a new local constant, initialized to the value of the string or number at the caret.

    Introduce Local

    Creates a new local variable initialized to the selected expression. Replaces the selection with the new variable.

      IntroduceLocal
    After applying this refactoring, the new local variable name is selected and linked up...

      AfterIntroduceLocal
    So it is easy to rename...

      AfterIntroduceLocal2

    Introduce Local (replace all)

    Creates a new local variable initialized with the selected expression. Replaces the expression everywhere it appears inside the code block with the new variable.

      IntroduceLocalReplaceAll

    Simplify Expression

    Resolves an expression to its simplest form. Simplify Expression will remove redundancy such as extra parentheses and sub-expressions that have no impact on the outcome of the evaluation. For example, consider the redundancy in the expression in the method below:

        SimplifyExpression0
    To simplify this, select the expression and press the CodeRush key (Ctrl+`). The preview hint shows how the expression will be simplified. Notice that we lose the redundant reference to the hasQualified parameter, and we also lose an extra pair or parens, resulting in a cleaner expression that is easier to read.


     SimplifyExpression

    Interfaces

    Extract Interface

    Extracts an interface based on public members in a class.

    Lambda Expressions & Anonymous Methods

    Compress to Lambda Expression

    CSharpSmall This refactoring is only available in C#.

    Converts an anonymous method to an equivalent lambda expression.

      CompressToLambdaExpression

    Expand Lambda Expression

    CSharpSmall This refactoring is only available in C#.

    Converts a lambda expression to an equivalent anonymous method.

    Inline Delegate

    CSharpSmall This refactoring is only available in C#.

    Inlines the delegate, creating an anonymous method. If there are no other references to the delegate method, it is removed.

      InlineDelegate

    Name Anonymous Method

    CSharpSmall This refactoring is only available in C#.

    Creates a new delegate method from an anonymous method which does not access any local variables from the parenting method body.

    NameAnonymousMethod 
    After applying this refactoring the method names will be linked up allowing you to easily rename the new method.

    Loops & Blocks

    Add Block Delimiters

    CSharpSmall This refactoring is only available in C#.

     

    Embeds a child statement inside brace delimiters.

      Before:
      if (files == null)
        files = Directory.GetFiles(_StartingFolder);

      After:
      if (files == null)
      {
        files =
    Directory
    .GetFiles(_StartingFolder);
      }

    Create With Statement

    VBSmall This refactoring is only available in Visual Basic.

    Creates a Visual Basic With statement for the specified instance within the selection.

      CreateWithStatement

    If more than one qualifying instance exists, a sub menu will allow you to select the instance to become the subject of the With statement.

    Inline With Statement

    VBSmall This refactoring is only available in Visual Basic.

    Inlines the object reference of a Visual Basic With statement into all dot-references.

      InlineWithStatement

    Remove Block Delimiters

    CSharpSmall This refactoring is only available in C#.

    Removes unnecessary brace delimiters in C#.

      Before:
      if (files == null)
      {
        files = Directory.GetFiles(_StartingFolder);
      }

      After:
      if (files == null)
        files = Directory.GetFiles(_StartingFolder);

    Properties & Fields

    Convert to Auto-implemented Property

    CSharpSmall This refactoring is only available in C#.

    Removes the backing store and converts the active property to a C# auto-implemented property. Available when the caret is on the property name.

      ConvertToAutoImplementedProperty

    Convert to Auto-implemented Property (convert all)

    CSharpSmall This refactoring is only available in C#.

    Converts all properties in the active C# type to auto-implemented properties, removing the associated backing store fields.

    ConvertToAutoImplementedPropertyConvertAll

    Create Backing Store

    CSharpSmall This refactoring is only available in C#.

    Converts a C# auto-implemented property to a conventional property with a backing store.

      Before:
      public string StartingFolder { get; private set; }

      After:
      private string _StartingFolder;
      public string StartingFolder
      {
       get
       {
        return _StartingFolder;
       }
       private set
       {
        _StartingFolder = value;
       }
      }

     

     

    Encapsulate Field

    Encapsulates a field into a read-write property and replaces all occurrences of this field with the newly declared property. In C# control is passed to the built-in refactoring that encapsulates fields. In Visual Basic CodeRush Xpress implements this refactoring.

    Encapsulate Field (read only)

    Encapsulates a field into a read-only property and replaces all read-references to this field with the newly declared property.

    Method to Property

    Creates a property from the current method.

      Before:
      public string GetStartingFolder()
      {
        return _StartingFolder;
      }

      After:
      public string StartingFolder
      {
        get
        {
         
    return _StartingFolder;
        }
      }

    Property to Method(s)

      For read-only properties:
        Converts the property into a function.
      For write-only properties: 
        Converts the property into a method (or Sub in Visual Basic).
      For read/write properties: 
        Converts the property into two methods, creating a new function for the getter, and a new method for the setter.

    Moving/Extracting Methods

     

    Extract Method

    Creates a new method from the selected code block. The selection is replaced with appropriate calling code to invoke the newly-declared method.

    CSharpSmall In C# control is passed to the built-in refactoring that extracts methods.  VBSmall In Visual Basic CodeRush Xpress implements this refactoring.

    ExtractMethod

    Extract Method to Type

    Creates a new method from the selected code block and moves it to the specified type, updating the selected code block appropriately. The selection is replaced with suitable calling code to invoke the newly-declared method through an instance of the target type. This refactoring is useful when you have a block of code that references several properties or methods on a variable of a type that is declared elsewhere in your solution.

      ExtractMethodToType

    After extracting the code block above, the new method looks like this:

      ExtractMethodToType1

    And the calling site looks like this:

             ExtractMethodToType2 

    Extract Property

    Creates a new property from the selected code block. The selection is replaced with appropriate code to reference the newly-declared property.

      ExtractProperty
    After extraction the property name is selected and linked up for an easy rename.

      ExtractProperty2

    Replace Temp with Query

    Replaces each reference to this local variable with a call to an extracted method, which returns the initial value assigned to this local.

      ReplaceTempWithQuery

    Resource Files & Strings

     

    Extract String to Resource

    Extracts the string at the caret into a resource file.

      ExtractStringToResource
    After extracting the string, the resource identifier is selected and linked for an easy rename.

      ExtractStringToResource2

    This refactoring is useful if you have text that needs to be translated into one or more target languages. Placing all text that needs translation into a resource file makes it possible to change and add foreign language support without changing the code.

    Extract String to Resource (replace all)

    Extracts all matching strings in the file to a resource file.

    Extract XML Literal to Resource

    VBSmall This refactoring is only available in Visual Basic.

    Extracts the active embedded XML literal to a resource file.

      ExtractXMLLiteralToResource 

    After the extraction the resource identifier is selected and linked up for an easy rename.

      ExtractXMLLiteralToResource2 

    Use String.Format

    Converts a composed string expression into a single String.Format call.

    UseStringFormat

    Notice in the preview hint how the formatting arguments passed to the ToString calls in the original expression (e.g., "listPrice.ToString("c")") are properly converted to the appropriate format strings (e.g., "{0:c}").

    This refactoring is useful if you have concatenated display text such as this that needs to be translated into another language. Complete sentences are more effectively translated than sentence fragments, as they can be grammatically rearranged as is sometimes necessary with translation, without touching the code.

    Use StringBuilder

    Replaces the selected string concatenation operations with corresponding method calls on a local StringBuilder instance. For example, consider the following code:

                 UseStringBuilder0 
    To change these string concatenation operations to equivalent code that works uses a StringBuilder, just select the text to convert and press the CodeRush key (Ctrl+`).

    UseStringBuilder1

    The preview hint gives you an idea of the changes this refactoring will apply to the code. Old string concatenation operations ("+=") are updated.

              UseStringBuilder2
    Notice also the intelligent changes applied to the second line that had previously called String.Format. That call has been converted to an AppendFormat call.

    Types

    Move Type to File

    Creates a new file with the same name as the type at the caret, adds the file to the project, and then moves the type to that file, along with any leading comments, attributes, and XML doc comments. This refactoring is available when the caret is on a type declaration and the file contains two or more types.

      MoveTypeToFile 
    After applying this refactoring, the type is moved to a new file with a matching name, and added to the active project:

      MoveTypeToFile2

    The new file is activated so you can work in that file if needed. As always, when a feature in CodeRush Xpress takes you away from where you started, you can get back to the original location by pressing Escape.

    Visibility

    Widen Scope

    Moves a variable declaration up (out) in scope, increasing the area where it can be referenced within the method.

    WidenScope

    Widen Scope (promote constant)

    Moves the local constant declaration out of the member and up to the type, replacing all matching values in the type with a reference to the constant.

    Widen Scope (promote to field)

    Converts a local variable to a field variable.

      WidenScopePromoteToField

    More Information

    Documentation on all the features of CodeRush Xpress, including samples in both C# and Visual Basic, can be found in the Visual Studio help after installing. Just select the Help | Contents menu item:

    HelpContents

    The help also includes sample animations for C# and Visual Basic, so you can see the features in motion.

    HelpAnimations

    Download CodeRush Xpress - free from Dev Express!

  • Performance and Memory Milestones in CodeRush and Refactor! Pro - Preview of 9.2

    The IDE Tools team has been spending a great deal of time making CodeRush and Refactor! Pro run even faster and with less memory. With every release since 3.2.3, customers have noticed improvements in speed. And it's no different for CodeRush 9.2, expected later this quarter.

    Performance

    Our primary focus for performance in this release has been solution load times. Specifically, we want to reduce the time it takes to go from specifying a solution to open in Visual Studio to the ability to refactor anywhere that a solution (we call this "zero-to-refactor" time). Refactoring anywhere means CodeRush has a full understanding of all the code in the entire solution.

    To give you an idea of what you can expect in CodeRush 9.2, we took some measurements of this zero-to-refactor time with three of our internal DevExpress solutions. Two of these solutions are among our largest: DX Controls (8000+ files, anyone? Holy crap!) and XAF. The third is a medium-sized project, XtraScheduler. The table below gives you an idea of their respective sizes using a variety of metrics:

     

    DX Controls

    XAF

    XtraScheduler

    # of Projects

    51

    54

    9

    # of Files

    8,056

    1,980

    660

    # of Types

    17,351

    4,295

    2,235

    # of Members

    209,384

    32,250

    22,215

    Lines of Code

    1,831,086

    255,759

    389,954

    Source Size

    84MB

    16MB

    18MB

     

     

     

     

     

     

     

     

     

    How do your solutions compare to these?

     

    Some details on the test machine:

    Processor

    Intel Core 2 Duo E6400, 2.13 GHz

    Memory

    2 GB

    Hard disk drive

    Seagate st3250824as, 7200 RPM

    (8ms average seek time,

    9ms average write time)

    Operating system

    32-bit Vista, SP1

    And it's Windows Experience Index:

     WindowsExperience

     

    First Time Loads

    When you first open a solution, CodeRush 9.2 parses it and caches important information using a background thread. The cache later improves the zero-to-refactor time for subsequent loads of the same solution.

    The parse and cache-building times for first-time loads for each of the solutions in CodeRush 9.2 are about the same as the old parse times (and no cache building) for CodeRush 9.1:

     FirstTimeLoad3

    Even though CodeRush 9.2 performs additional functionality on the first-time load (e.g., parsing the code and building the cache), the team has actually found ways to improve the parsing speed sufficiently so as to have an overall effect of marginally reducing the zero-to-refactor time.

     

    By the way, if you are looking at that 200-second parse and cache-building time for the DX Controls project and on the verge of freaking out, you may find relief in the following:

    1. That time is from zero (no solution open) to the ability to instantly initiate a refactoring anywhere (no build required).
    2. This is all happening in a background thread. Visual Studio remains responsive during this time.
    3. The DX Controls solution declares over seventeen thousand types and over two hundred thousand members. It's 84MB of source code and nearly two million lines of code long. This solution is significantly larger than most solutions out there.
    4. This cache-construction stage only occurs once -- the first time you open a solution without a cache.
    5. This zero-to-refactor performance for first-time solution loads is actually comparable if not significantly faster than the competition.

    Subsequent Loads

    For subsequent solution loads after the cache is built, the story is even better:

    SubsequentLoad2 

    Notice that once the cache is built, subsequent times to load a solution and get from zero-to-refactoring for CodeRush 9.2 (middle row in red) approach those of Visual Studio's normal load time for the solution (front row in blue).

    The bottom line is CodeRush 9.2 gets you to that point of total code understanding where you can refactor anywhere significantly faster than CodeRush 9.1. In some cases up to five times faster.

    Memory Consumption

    Remarkably, the memory story is even more compelling than the performance story.

    The data below shows total Task Manager memory after loading one of these large solutions and reaching that point where we're able to refactor anywhere in the solution (all source code has been parsed). Measurements were taken with Visual Studio 2008 alone (no add-ins), and with CodeRush 9.1 and CodeRush 9.2.

    MemoryConsumption2

    By the way, if you're using a competing IDE productivity tool and wondering how much memory that other tool might be consuming, it's likely to be very close to the memory consumed by CodeRush 9.1 (see the back row in purple).

    Notice the significant drops in memory consumption produced by CodeRush 9.2 (middle row in red) compared to the memory consumption of CodeRush 9.1 (or your other IDE productivity tool). The savings in memory is huge, especially considering the size of these projects and the fact that this memory also holds all the assemblies required simply to keep CodeRush (and Refactor! Pro) running.

    The percentage numbers in white near the top of each bar show how much additional memory is required by CodeRush (to represent the entire solution as well as its referenced assemblies) as a percentage of that needed by Visual Studio alone (if you didn't have CodeRush installed).

    Whereas CodeRush 9.1 (in purple) requires about double the memory Visual Studio needs, CodeRush 9.2 requires substantially less. We expect most customers with large solutions to see a reduction in memory consumption of at least 100MB. Customers with very large solutions (e.g., 2000 files and up) should see even greater savings.

    Can I Try This Now?

    Yes you can. Between now and the release of CodeRush 9.2, CodeRush customers can request a daily build of CodeRush 9.2 from support@devexpress.com.

  • More Proof I'm a Genius - Behold My New DevEx Marketing Plan

    So, unless you've been coding under a rock for the past week, you're no doubt aware that once again the world's tightie whities are in a tizzy over the swine flu.

    This of course all hits us only days before Tech Ed 2009, where Dev Express will be bringing its financial muscle to the gun show a la platinum sponsorship.

    You may also recall that the Millahnator has been recently locked-out of Dev Express marketing meetings, because, well, the marketing folks at our company get all uptight whenever they find themselves in the presence of a marketing genius such as myself.

    But the Millahnator will not be detered by some smarty-pants in security changing the access codes on my teal badge. I know when it's time to take the reigns of this company into my own hands. After all, if the forces that be didn't really want me to take initiative, then why did they give me a company credit card?

    Exactly.

    And so yesterday afternoon I put the old Dev Express company credit card to good use. After treating my mind to an expensive dinner at Morton's Steak House, I reclined back in my Morton's Steak House chair and thought and thought, just like Winnie the Pooh after taking a pawful of hunney.

    I asked myself these questions:

    • How can DevExpress capitalize on the latest pandemic fear that is gripping this nation's developers?
    • How can DevExpress assuage the concerns of developers attending TechEd?

    Then it hit me. DevExpress Face Masks!

    The DevEx Face Mask -- Just in Time for Tech Ed

    After all, if being able to order 10,000 of these specially-branded Dev Express face masks without consulting anyone isn't what company credit cards are for, then I don't know what they're for.

    See you at Tech Ed 2009, kids! :-)

  • CodeRush Xpress 9.1 Beta for C# and Visual Basic Developers

    Alright kids, we've got some exciting news. The CodeRush Xpress 9.1 beta is now available for download. It's packed with crazy powerful features, for both C# and Visual Basic developers working in Visual Studio 2008. This product is free, licensed by Microsoft on behalf of Visual Studio 2008 developers everywhere.

    Here's a quick overview of what you get in this free download....

    59 Refactorings. That's right, 59 refactorings. And you get some really powerful refactorings here including Decompose Parameter and Extract Method to Type.

    17 Consume-first providers. You've got to see these in action to realize how powerful they are and how well they partner with Visual Studio's built-in Intellisense. Use Intellisense to build an expression, and use CodeRush Xpress to instantly declare the variable to hold it.

    Powerful navigation tools. Such as Tab to Next Reference, CamelCase Nav, Quick Symbol Nav and File Nav.

    And so much more. Smart Cut, Smart Copy, Structural Highlighting, and Duplicate Line, to name a few.

    Videos to get you started:

    C#       Visual Basic

    (note, the links at the end of the videos telling you where to download CodeRush Xpress 9.1 are not yet published -- use the links in this blog post instead)

    This could be the most powerful no-cost developer tool created ever, in the history of all time!

    Remember kids, this beta won't last forever, so get it here, and get us some great feedback ASAP!

  • New Video -- New CodeRush Features for ASP.net Development

    This video shows templates, navigation features, selection embeddings, and refactorings for ASP.net and HTML development inside Visual Studio, with CodeRush and Refactor! Pro:

    CodeRush Features for ASP.net Development

     http://tv.devexpress.com/CodeRushFeaturesHTMLDevs.movie

    Check out Cell Nav, and the simple yet elegant UI for creating HTML tables.

  • Refactorings Shipping in Refactor! Pro 9.1

    With the 9.1 release of Refactor! Pro, we bring the count a few refactorings closer to 200. This release only adds a small handul of refactorings, but that's okay since a great deal of our focus has been on improving performance and reducing memory usage. Click below to get the same spreadsheet we use internally to track all the refactorings. You can sort, filter or group by language supported, version number, or refactoring category.

    Refactorings in 9.1

  • What's New in CodeRush & Refactor! Pro 9.1

    9.1 is out. Here's what's new in CodeRush and Refactor! Pro since 3.2:

    New Version Number. We are now synchronizing our version numbers and releases with the rest of the DXperience product line. Here's how you can make sense of the version number:

    91

    Faster Performance. Performance should be noticeably faster in most areas of the product, especially on large projects. Startup time, project opening time and editing performance have all been affected by this work.

    Reduced Memory Footprint. Memory usage has been reduced significantly, and should be especially noticeable when working with large projects.

    Code Issues. Code issue technology is now shipping. This new technology shows redundant code, hints, warnings, errors, and design-related problems (a.k.a. "code smells") while you work, and also binds to CodeRush's CodeProvider technology and Refactor! Pro's refactoring technology, so you can quickly apply fixes to a number of detected issues.

    CodeIssues

     

    Feature Control. Now when a CodeRush feature executes, you'll get confirmation and an instant way to keep that feature active or disable it. For example, if our default shortcut conflicts with an existing Visual Studio shortcut, you'll have an opportunity to decide which feature wins. Here's an example:

    When the modeless feature control window appears, you can:

    • Ignore it and simply continue to work.
    • Click one of the "Always do this" links to enable or suppress the feature.
    • Click one of the shortcut links (e.g., "Tab" in the screen shot above) to change the shortcut binding to something else.

    Note: If you disable a feature, you can re-enable it on the Core\Features options page.

    HTML Selection Embedding. You can embed HTML selections in a variety of useful tags, including:

    • Bold (<strong>)
    • Italics (<em>)
    • Underline
    • Anchor
    • Div
    • Paragraph
    • Table

    Just select the text you want to embed and press the CodeRush/Refactor key (Ctrl+` by default), select "Embed Selection" and the tag you want to wrap with.

    EmbedBold

    HTML Templates. We've added powerful new templates for HTML developers. These templates appear in the CodeRush Training window (DevExpress | Tool Windows | CodeRush). Supporting both ASP.NET and raw HTML, these templates make it much easier to create content from the source window. Here's a partial list of HTML templates in this release (use the CodeRush Training window to see them all):

    HtmlTemplates

    These HTML templates are smart and will generate unique values for the ID, Name, and Value properties as needed.

    The table templates (.t, .thf, and t appearing in the screen shot above) include UI that makes it easy to create tables of any size. For example, I can create a 2x5 raw HTML table in four keystrokes (".t", Space to expand, followed by Enter to accept the table dimensions).

    TableSize 

    HTML Cell Navigation. Once you have your table, you'll want to navigate through its cells. We've made this easy, too. Just press the Tab key when the caret is inside a table cell, and Cell Nav will take you to the next cell in the table.

     TableNav

    And of course Shift+Tab takes you to the previous cell.

    Cell Nav even understands cells that span multiple columns:

    ColSpan

    And you can use the mouse to get to the cell you're interested in.

    MouseToCellNav

    Now that you can navigate quickly through your tables, we thought you'd also want to be able to navigate just as efficiently through the items in your list controls (e.g., DropDownList, BulletedList, select, etc.). And so you can. Just press the Tab key to navigate through the items.

    ListNav

    CodeRush developers familiar with Tab to Next Reference are no doubt beginning to detect a pattern here. :-)

    New Refactorings. This release includes a few new refactorings:

    • Compress Assignment. Compresses this assignment to a short form assignment. For example, converts "a = a + b;" (in C#) to "a += b;".
    • Expand Assignment. Expands this short form assignment to a full assignment.  For example, converts "a += b;" (in C#) to "a = a + b;".
    • Split Using Statement. Splits this multi-declaration using statement into two or more neighboring using statements.
    • Sort Namespace References. Sorts namespace references in the current file.

    Code Providers. There are some powerful new code providers (including a spell checker!) as well:

    • Declare Properties. Generates auto-implemented properties for an object initializer expression.
    • Declare Fields with Initializers. Adds fields and initializes it to each parameter of a constructor.
    • Declare Property with Initializer. Adds an auto-implemented property and initializes it to the parameter under the caret.
    • Declare Properties with Initializers. Adds auto-implemented properties and initializes them to each parameter of this constructor.
    • Declare Method (abstract). Generates an abstract method for the method call with appropriate parameters.
    • Convert to Procedure. Converts a function that returns an object into a method that returns void (or a Sub in VB).
    • Convert to Function. Converts a method that returns void (or a Sub in VB) into a function that returns an appropriate type. Note: I use this one frequently. Just add a value to a return statement inside a proc, place the caret on the return keyword, and press the CodeRush/Refactor key.
    • Convert to Auto-implemented Property. Converts an unimplemented property into an auto-implemented property.
    • Convert to Property with Backing Store. Converts an unimplemented property into a property with backing store.
    • Spell Checker. Corrects a spelling error in a comment or string.

    We hope you enjoy this new release. We're not finished with our work on performance and memory. We expect the 9.2 release to be even faster with an even smaller footprint. Looking forward to your feedback on 9.1.

    Oh, one more thing! CodeRush, Refactor, and a host of other DevExpress products are in the running for the asp.net PRO readers choice awards. Please vote for your favorite tools and controls. Thanks to everyone in advance!

  • Prepping for the 9.1 release of CodeRush and Refactor! Pro

    We're all deep in the final stages of prepping for the 9.1 release of CodeRush and Refactor! Pro. That explains the relatively quiet front out here. The jump in version numbers synchronizes with the rest of the product releases here at Dev Express. The 9 corresponds to 2009, and the 1 signifies the first release of the year.

    I'm currently working on an plug-in that HTML devs should be excited about, and in it I noticed the following code:

          if (leftSideIsWhiteSpace && rightSideIsWhiteSpace)
            ea.Satisfied = true;  // On an empty line.
          if (!leftSideIsWhiteSpace)
            ea.Satisfied = true;  // Text to the left.

    You may have spotted the redundancy here. Fortunately, I have Refactor! Pro. So I can place the caret on the if statement, press the CodeRush/Refactor! key, and choose Combine Conditionals, which gives me this (sans redundancy):

          if (!leftSideIsWhiteSpace || rightSideIsWhiteSpace)
            ea.Satisfied = true; // On an empty line.
          // Text to the left. 

    Nice. :-) Now I can manually combine the comments into something more meaningful, like "// Text to the left or on an empty line" and I'm done.

    I will be back soon with previews of what's you can expect in 9.1, including some powerful sweet fun code creation and navigation features for HTML developers. And after 9.1 is out I'll return to the Science of Great UX blog series.

     

     

     

  • Great UI: Clarity and Color on the Presentation Layer

    Color consists of:

    • Hue Hue
    • Saturation Saturation
    • Lightness Lightness

    Consider the images below:

         
    On the left gaze attracts toward the deeply saturated hues, and the mind grapples with the hue variance and attempts to discern meaning (of which there is none).   On the right, with all shapes represented in the same hue, gaze attracts toward interesting details and the mind attempts to discern meaning from shape, of which there is a great deal.

    From this, an important lesson:

    Hue variance should justify itself.

    Two screen shots from the iTunes installer: one real; one altered.

     
    On the left you have an interesting variety of hues, with saturation and lightness apparently disconnected from information relevance.    On the right the same data is represented with only a single hue. Saturation and lightness levels are consistent with the information presented.

    Which image would you rather see during an install?

    So hue variance must be justified. Following this guideline over time, we eventually realize a second, important guideline:

    Fewer hues is better.

    Now let's move to an example that pretty much disregards that guideline. Here's a screen shot from an Excel spreadsheet we use to track refactorings shipped in Refactor! Pro (click to see the full-size image):

    In this spreadsheet, each language supported has a dedicated color (e.g., C# is red, VB is green, C++ is orange, etc.). Also, at the far right of the spreadsheet we track the version where each refactoring was introduced, and also we also note whether that refactoring ships in CodeRush Xpress or Refactor! for Visual Basic. Here too color carries meaning, and is useful. If you're interested in refactorings that only support XAML, for example, you can scan your eyes down and look for a blue circle in the XAML column.

    The column headers serve as a legend of sorts, connecting color to the data it represents:

    We even follow this convention in descriptive text inside the spreadsheet, for example in this description for the Rename refactoring:

    Speaking of Excel, the Excel application itself uses color in an interesting way. When editing formulas, Excel uses color to connect the cell reference in the formula to the cell on-screen. In the screen shot below, the cell reference "R[-4]C" is rendered in blue, and there is a corresponding blue box surrounding that cell:

    On to a practical example. Let's say we have an application that presents sales data to managers, like this:

    Managers using this application want to quickly see the best and worst members of the sales team.

    So let's use red to indicate the lowest values, and green to indicate the highest values.

    That's not too bad. Now at a glance we can see the best and worst performers for any quarter. And we've reached a third guideline:

    We can enhance clarity with color.

    Sometimes I hear developers say:

    "You shouldn't use color at all to convey meaning, because a significant percentage of the population is color blind."

    Is this a reasonable guideline to follow?

    Let's find out.

    First, a bit of background: Color blindness affects 8.6% of males and about 0.4% of females (or 4.5% of the entire population). Our eyes detect low-light variances with rod cells, and full spectrum bright-light variances with cone cells, of which there are three types: L-cones, M-cones, and S-cones. When there is a defect or absence in one of these groups of cones, color blindness occurs. Many of the color vision genes fall on the X chromosome, which is why color blindness occurs more frequently in men.

    Here's the color vision breakdown for humans on this planet:

    In addition to the percentages listed at the top, each color vision category in the figure above includes a list of six named colors, rendered as a person in that category would view them. Note that for the two most prevalent forms of color blindness (M-cone defect and L-cone defect), differentiating between red and green, as well as between blue and magenta, is challenging if not impossible.

    Notice however that for all categories listed, differentiating between red and blue is relatively easy.

    How does this impact our widget sales application? For someone with an M-cone defect, the data looks like this:

    And we lose our at-a-glance ability to see the highs and lows. But what if we take the information learned above, and instead of using red and green, we differentiate with red and blue? Then to someone with normal vision, that change looks like this:

    And to someone with an M-cone defect, the same data would look like this:

    And so we are able to keep with the intent of using color to convey meaning, and do so in a way that works even with people who are color blind.

    And we have a new, important lesson:

    When conveying meaning with color, use reds and blues to differentiate, rather than reds and greens.

    Speaking of conveying meaning with color, you might be wondering what Excel's cell-reference color-highlighting looks like to someone with an M-cone defect. It looks something like this:

    As you can see, we get into trouble with Excel's choice of color for the first and third cells referenced in the formula. The blue and magenta both appear blue, and are nearly impossible to distinguish. Here are sections of the two views, enlarged:

    Should Microsoft address this? Well, let's look at the impact. Editing formulas is something most Excel users do at some point with the product. So it's a highly visible feature of the product. Excel has over 450 million users, and that means over 20 million color blind Excel customers are impacted by this choice. Seems like the answer is a resounding Yes.

    So how can the Excel team fix this? One option would be to slightly increase the lightness of the third color, magenta, so it appears as a lighter blue to someone with an M-cone defect, making it easier to distinguish from the first color. That simple change would look like this:

    All this leads us to a final lesson about color:

    When conveying meaning with color, differentiate by varying lightness in addition to hue.

    So here are the guidelines for color, once again:

    • Justify hue variance.
    • Fewer hues is better.
    • We can enhance clarity with color.
    • Use reds and blues to convey meaning, rather than reds and greens.
    • Convey meaning by varying lightness in addition to hue.

    Coming soon, we'll discuss clarity and noise. After that we'll dive into the second essential component of Great UI: efficiency.

  • Great UI and the Presentation Layer - Clarity and Shape

    In our last post, we saw that information in parallel allows viewers to more efficiently understand data on the presentation layer.

    In today's post, we'll talk about conveying information with shape (e.g., something other than a rectangle).

    Non-rectangular shapes can fulfil a variety of objectives:

    • Create a smaller footprint (so more background information is visible).
    • Model a physical device from the real world.
    • Convey information more dynamically, using conventional graphic elements

    When using non-rectangular shapes it is important that the shape serve some purpose.

    When the purpose is whimsy, you get windows like this:

    Ducky 

    In the ducky media player, above, we're actually creating a larger footprint instead of a smaller one. And the only device we're modeling is a bathtub, and last time I checked, this has nothing to do with playing media (at least not in my house). So from my perspective, this non-rectangular shape fails spectacularly.

    And so does this one:

    Bird

    In the examples above, the custom shapes waste a phenomenal amount of space, and simply do not justify their non-rectangular being.

    Here's another non-rectangular window:

    ShortcutHint

    This is the shortcuts hint from Refactor! Pro and CodeRush. This window shows shortcuts available for interactive states. The tab at the top holds the name of the interactive state.

    Compared to a similar design employing a rectangular window, this custom shape permits more background information to be seen:

     BackgroundDataVisible2

    So the benefits are minor, but then again so are the changes, and so the non-rectangular shape justifies itself.

    Speaking of custom shapes and subtle changes, compare the impact of slightly rounded corners against squared-off corners:

     RoundedCorners2

    The sharp corners attract gaze, whereas the rounded corners appear more natural, and are easier to ignore.

    Custom shapes can also be used to reveal details of densely-packed information. The screen shot below is from the 3.3 version of CodeRush.

    DocBarHint

    The document bar to the right shows code issues for the file, however when a file has more lines than there are pixels in the height of the document bar, and there are many issues in a short span of code, you can have overlap. When that happens, the most serious issue is painted in the document bar (the horizontal red line indicates the error).

    Hovering the mouse over the horizontal line in the document bar reveals the details about the densely-packed information below. The custom shape effectively connects the expanded details to the compact representation. The visual connection is instantly assimilated. For this application, the benefits of that instant understanding justify the custom shape.

    Here's another non-rectangular shape:

    ActionHint 

    This shape appears when certain commands are executed inside CodeRush and Refactor! Pro. The arrow points at the location of the change, and the text inside holds the name of the feature applied.

    More custom shapes, from Oliver Sturm's Instant Gratification plug-in for Visual Studio:

    RTFM   CompiledBaby   YouRule

    Here, the semi-opaque text layered on top of the data provides temporary status information (in this case, immediate feedback on whether the latest compile actually succeeded or not). This text is created as a window, and displayed in a semi-opaque state on top of the data below.

    And finally, we'll wrap up with a custom shape you have probably seen before:

    DeviceReadyToUse

    This shape has rounded corners and a point that connects the information contained within to the applicable task bar item below. This shape is particularly effective as it uses the conventional graphic element, the bubble call-out, to provide useful information in a non-modal way.

    One interesting thing to note -- with the exception of the duck and penguin media players shown above, all examples of non-rectangular windows shown here are used in some way for discoverability, which we'll talk about much, much later in the series.  :-)

    From the standpoint of clarity, if you're going to use a custom shape, the most important guideline to keep in mind is this: Non-rectangular shapes should justify their existence. Justification comes from tangible benefits, such as a smaller footprint, familiarity through the modeling of a physical device, or using conventional graphic elements, such as call-outs, or large arrows, to connect information to specific points of interest on screen.

  • Great User Interfaces, Clarity, and Information in Parallel

    In the last post, we talked about the elements of design we can adjust to match information relevance. In this post, we'll talk about another, equally important guideline to presenting with clarity, called information in parallel.

    This concept is introduced in an amazing book by Edward Tufte:

    TufteBook Title: Visual Explanations: Images and Quantities, Evidence and Narrative

    ISBN: 0961392126

    The book and title both look dreadfully dry. However, proof of Tufte's genius lies therein.

    The idea behind information in parallel is simple. It's much easier for humans to compare and understand when they see information side-by-side, rather than when the same data is presented in serial. This is crucial for user interfaces, because the very nature of software -- representing a large amount of information in a constrained space -- lends itself to solutions that tend toward the presentation of information in serial.

    Take for example, the trusty standby, the modal dialog box. Since the age of windows, modal dialogs have been with us. Two questions:

    1. Have you ever clicked the mouse down on the title bar of a modal dialog, the dragged it off to the side just so you could see something underneath it?
    2. Have you ever clicked the Cancel button on a modal dialog, just so you could access information behind it (perhaps copy some text to the clipboard),  information necessary for successful interaction with the dialog itself?
    3. Have you ever had to click the Back button on a browser, to see a previous page, just so you could then immediately click the forward button to use that information on the current page?
    4. Have you ever had to scroll up when viewing a document, just so you could see information above necessary to understand the information below?

    If you answer yes to any of these questions, then you may be the victim of information presented in serial.

    Examples of information in serial include:

    • Audio podcasts
    • PowerPoint presentations
    • Stacked modal dialogs
    • Wizards
    • A long paragraph of text.

    So far in covering the science behind great user interfaces, a number of comparisons have been presented using information in parallel. Some examples you may remember:

    A failure of efficiency in Why is Great UI so Hard to Achieve?:

    TwoPaths3

     

    A failure to match visual weight to information relevance, from a table in Microsoft Word, from Great UI, Clarity, and Information Relevance:

     BothTablesSideBySide3

    An illustration showing how adjusting too many elements of emphasis (e.g., saturation, size, and contrast) can lead to visual noise, in Great User Interfaces, Clarity, and Emphasis:

     VisualWeightRansom2

    Let's compare information in parallel with information in serial, to see how they differ.

    Information in parallel is more effective than information in serial, because it can be exploited by our eyes which are excellent at quickly moving back and forth. All layers are simultaneously visible, and the viewer has full control over the pacing and the sequence in which information is understood. Information in serial, on the other hand, burdens the viewer with pacing challenges (information may arrive too quickly or too slowly). Viewers also have no control over the sequence of presented information when arriving in serial.

    That last paragraph was an example of information in serial.

    Here's the same data presented in parallel:

    A viewer can... Serial Parallel
    Control the pacing of information: No Yes
    Control the sequence of information: No Yes
    See all information simultaneously: No Yes

    Notice when information is presented in parallel, our eyes can move back and forth, easily and quickly comparing data in the columns at a pace that feels right.

    One note about pacing and information in serial: Sometimes UI provide viewers with a mechanism to control pacing, as in the example of a wizard dialog that allows you to navigate forward or backward through its pages. This all comes at the expense of introducing an interaction mechanic (e.g., reaching for the mouse to click the Next or Back buttons) that is likely to be far less efficient than simply shifting gaze, which is all it takes to control pacing with information in parallel.

    So the goal is to take a serial interface (e.g., stacked modal dialogs) and flatten that out. How can we do this?

    Well, it isn't easy. It often requires careful thought applied to layout as well as an understanding of what information is essential and needs to be readily available, and what information is less important. Sometimes it requires innovation, in the form of new user interface elements. Let's look at an example from the world of software development.

    Let's say your challenge was to create a user interface that assisted developers in reordering parameters in a method declaration. Using traditional software-building tools, you might crank out a modal dialog that looks something like this screen shot taken from Visual Studio 2008:

    ReorderParametersVS

    There are good things here, and there are also some undesired consequences. Let's talk about the good first. There are two:

    1. The dialog appears under the method you are trying to rename, so that the source code you are trying to change, as well as the dialog itself, are both in view. This is information in parallel.
    2. The Preview method signature box shows the impact of your changes before you apply them. This is also information in parallel.

    Next, the issues:

    1. The dialog hides a significant amount of otherwise visible code in the document. When a window hides information below it, this is information in serial.
    2. The user model changes. Developers are used to working with the keyboard and source code, but now developers have to adapt to a new unfamiliar model, one that uses a grid, buttons and mouse clicks to manipulate code.

    So, how do we flatten this down? Is there a way to remove the dialog completely, yet still allow interaction with a preview before changes are committed? The answer is yes. Here's how we do it:

    1. Move the UI elements down to the lowest layer of the UI (the source code, in this example).
    2. Introduce a similar state-like ability for the interactive phase (where developers can reorder the parameters without reaching for the mouse and without having to adapt to an unfamiliar representation of method signatures).

    That UI might look something like this:

    ReorderParametersInRefactor2

    On the good side, we've removed the modal dialog that blocked out so much of the code. And we've introduced an interactive phase that allows parameters to be reordered without reaching for the mouse (efficiency gains) while keeping a familiar representation of the data (clarity gains). On the downside, in keeping with the familiar representation of the code and losing the dialog, this in-source interactive phase will no doubt be an unexpected surprise the first time developers encounter it. So we compensate, improving discoverability by adding the shortcut hints window in the lower-left.

    So yes, flattening the UI can take some effort, and even the introduction of new UI elements or states. However the gains in efficiency and clarity (and sometimes even discoverability), can make it all worth it.

  • Great User Interfaces, Clarity, and Emphasis

    In our previous post in this series, we established an important guideline to achieving clarity:

    Visual weight should match information relevance.

    The essence of this guideline, is don't overdo it. So as we discuss ways to control emphasis, remember that the goal is to be subtle, to emphasize with what Edward Tufte refers to as the smallest effective difference.

    Contrast

    The easiest, and most powerful way to control emphasis is with contrast. Here's another screen shot from Adobe Lightroom:

    LabelsAndData

    Notice the less relevant labels on the left are rendered in a slightly lower contrast than the more important data on the right.

    Saturation

    Color can convey meaning, especially when used sparingly. In a sea of mostly black and white data, deeply saturated information will stand out.

    Trillian, an instant messaging client, has an interesting option to render non-focused windows in a semi-transparent state, or in gray scale. Here's an example. On the left, the window is focused. On the right, unfocused.

    TrillianBlackAndWhite

    Opacity

    Opacity is related to saturation and contrast. As you increase transparency of graphical elements, both saturation and contrast will drop. Opacity can also be used to indicate elements that are partially available.

    Below are two screen shots from Visual Studio with Refactor! Pro loaded. The arrow in red explains the command that just executed. On the left the arrow is fully opaque, distracting, and hard to ignore. On the right the red arrow is partially transparent, much easier to ignore, and yet the text is also readable if needed.

    Opacity

    When we initially shipped Refactor! Pro, the arrows were fully opaque, and we received many complaints from customers that the arrows were too distracting. We changed the default opacity for the next release, and the complaints dropped to zero (and we even received several emails praising their usefulness). So by controlling opacity we can take a distracting UI element that contains useful information (but perhaps is rarely needed) and turn it into something useful that feels right.

    Font

    Use a bold font to draw gaze into essential or important meaning, as in the tool tip below, that describes the Change Case button in Microsoft Word:

    Bold2

    In the checkboxes below, notice how you can quickly find the control you need just by visually scanning for the important words describing the functionality you need:

    Bold

    Being able to emphasize portions of control text is important, and it's something you can do with DevExpress controls. Julian Bucknall shows you how in his post, Using DevExpress controls to get a great looking UI.

    Size

    Size can be useful for attracting gaze. You can combine larger size with a lower contrast to attract the eyes and let them move on to more relevant data below, as in the screen shot from the DXCore options dialog, showing the Recent Files options page:

    SizeOptionsDialog

    Here, the title of the options page, "Recent Files" is in a larger font, which makes it easier to see for users encountering this page for the first time. But the contrast between this title text and the background is also low, making it easy for repeat users of this page to ignore the title and move on to the more important elements of the UI.

    For another example, take a look at the the "Image Settings" text in the gray-scale screen shot in the discussion on Fonts, above.

    Wrapping Up

    The essence of clarity, from a design and emphasis point of view, is to selectively match a subset (generally one) of the following traits to information relevance:

    • Contrast
    • Saturation
    • Opacity
    • Size

    I've left out Font because to some degree it's a subset of Size, and just as I don't want you to create UI with low-relevance information rendered in high contrast, I also want to make sure you don't create UI that so strictly follows this guideline to the point that you're no longer following the guideline and instead creating UI that approximates a ransom note.

     VisualWeightRansom2

    The goal, after all, is clarity.

    For example, imagine a tree list of information. One could make the argument that sibling and cousin nodes have different levels of information relevance than their respective parents or children, and therefore should be each rendered in a corresponding font size and contrast. That line of thinking could produce something like the following, which shows all references to the decimal type in a C# project:

    References

    The problem here is that by going too granular with grouping and dividing of information relevance, and also by applying too many levels of emphasis (e.g., font size as well as contrast), with good intentions and the goal of clarity we actually end up introducing some visual noise in the form of the varying font sizes and contrast. And that noise interferes with the essence of what we're trying to achieve. So just like the first guideline essentially says "Don't overdo it." A second, perhaps equally important guideline to consider is "Don't overdo it (or go too granular) when matching emphasis to information relevance."

  • Great UI, Clarity, and Information Relevance

    Let's create a 3x4 table in word....

    NewTableInWord

    And let's fill the table with data....

       ArialTableInWord

    Now, at this point, we might pause to ask "What's wrong?". But before we answer, let's make the observation that in the table above, there are a number of graphic elements working together to convey information. There is the data, rendered as text:

       ArialTableInWord_DataOnly

    And there are lines separating the data:

       ArialTableInWord_LinesOnly

    Note that in Word, both the lines separating the data, and the data itself, are both rendered with essentially the same visual weight. The thickness of the line matches the thickness of the strokes used to render the text, and the contrast of the lines also matches the contrast of the text.

    However, it seems that the lines and the data, in terms of relevance to the viewer, are far from equal. A viewer is far more interested in the data than the lines separating the data.

    Let's look at the same table in Excel:

    SameTableInExcel2

    Notice that when creating the same table inside Excel, something interesting has happened. The lines are rendered in a much lower contrast than the data itself.

    Which table do you find easier to read?

     BothTablesSideBySide3

    On a whim, let's create a version of this table where we do the opposite of what's done in Excel. Namely, let's reduce the visual weight of the important data, while increasing the visual weight of the much less relevant separating lines:

    TableReversContrast2

    How easy is this to read, compared to the table from Microsoft Excel, above?

    So, two important points to take away:

    1. Not all information is equally relevant to the viewer.
    2. We have control over the degree to which we can emphasize information.

    And from these two realizations, you can reach the third, perhaps most important guideline to achieving clarity in your UI:

    Visual weight should match information relevance.

    This guideline is incredibly important, easy to follow, and yet violated frequently. My contention, as set forth in the post that explored the question of why great UI was so hard to achieve, is that the rampant violations can be explained by a lack of training.

    Here's a screen shot of Visual Basic source code as seen in Visual Studio 2008:

     SourceCodeInVisualBasic2

    The horizontal lines carry little information relevance. And even though they are rendered above in a medium gray, their contrast and corresponding visual weight far outweigh their intended purpose.

    Here's the same image with one minor change:

    SourceCodeInVisualBasic_Redesign

    See how much easier it is to get your eyes into the relevant data.

    Here's a screen shot from Adobe Lightroom:

    AdobeLightroom

    Notice how the labels on the left, being less relevant than the data to their right, are rendered in a lower contrast, allowing your eyes to quickly get to the relevant information.

    In near-future posts, we'll talk more about ways to control emphasis and dive deeper into clarity.

  • Why is Great UI so hard to achieve?

    Filling up my car with fuel this morning, I'm suddenly hit in the face with more evidence that the vast majority of user interfaces fail to satisfy those three important elements of great UI, clarity, efficiency, and discoverability.

    One of the common mistakes you see in the physical world are buttons on a single device designed as if they will all be pressed with the same frequency. You can tell this because the buttons are all the same size, and in some cases the buttons you have to hit most frequently are two small and located in places that require more thought and more precision to hit than they should.

    Speaking of buttons and precision, here's part of the interface I was looking at:

    FuelGradeButtons2

    On the left you have the button from a fuel pump that selects the most popular grade of gasoline in the United States. On the right sits the button for the less popular, more expensive grade of petrol. The erosion on the left is like a chart showing both frequency of hits as well as signaling where people wanted to hit the button. It is clear that humans who interacted with the button on the left wanted to work with a button far larger than the designed "Push Here" area afforded.

    Here's a redesign of this interface, keeping with the essence of the original:

     FuelGradeButtons_Redesign2

    Here are the changes (we'll explain the rationale behind these changes in future posts):

    • "GRADE SELECT" converted to the less-noisy "Grade Select".
    • The unnecessary underline below "Grade Select" has been removed.
    • The redundant "Grade Select" text has been removed.
    • The tabs holding the "Grade Select" text have been removed.
    • Button area increased and low-contrast border added.
    • Contrast of the "Push Here" labels has been lowered.
    • Contrast between the Regular and Plus text, and their backgrounds has been increased.

    So, while there is plenty of evidence that some buttons are pressed more than others, there isn't much evidence that designers actually understand that.

    One of my favorite large buttons is the space bar on a modern keyboard. Of course that originates from an ancient machine known as the typewriter. Unfortunately, the QWERTY layout that dominates today takes a step far, far away from efficiency by unbelievably moving frequently-accessed keys into harder to reach spots, reportedly because early adopters of typewriters with pre-QWERTY layouts were so proficient they would frequently jam the typebars of the machine together. I can't tell you how much I would like to be in on that meeting back in 1874 when they decided to move the keys around so they were actually harder to hit. That one decision had to be one of the most expensive user interface mistakes ever made, in terms of lost productivity multiplied over time. That space bar likely survived only because hitting it simply advanced the paper one character to the left -- and did not increase the risk of typebars getting wedged together.

    But it did survive and it's big and easy to hit with either thumb, so I like it. :-)

    You need to get to that cross walk over there in the distance on the right. Which path do you take?

    SideWalkAndPath

    On the left, the designers' intention is highlighted in red. On the right, the more efficient path is outlined in blue:

    TwoPaths3

    There is evidence humans prefer efficiency to flat hard ground.

    You're watching TV. You need to change the channel, and you need to change the volume.

    Which remote control would you rather hold in your hand?

    RemoteControls

    Which remote would you rather adjust volume on?

            CompareVolumeButtons 

    On the white remote control on the right, the channel-changing buttons on top are far away from the volume-changing buttons at the lower-right.

    ChannelVolumeButtons

    Also, these horizontal and vertical orientations are inconsistent and require some mental training before it feels natural. And the visual weight (shape, size, contrast) of these buttons is identical to nearly all the other buttons on the control, including the rarely-pressed buttons labeled Language and Clock.

    You're inside an elevator in the N-terminal at Seatac airport. You need to get on your plane. There are three buttons to select your destination:

    • CONCOURSE (CC)
    • RAMP (*R)
    • TRAIN (TRN)

    SeatacElevatorButtons1 

    Which button do you press? That RAMP button with the star next to it looks mighty appealing. After all, I must walk down a ramp to get onto my plane. And haven't I seen stars on elevator buttons used to indicate the main floor or lobby? And what's a concourse, anyway? I need to get to my gate, and it's in a terminal.

    Here's a wider picture of that elevator control panel:

    SeatacElevatorButtons2

    Apparently there was sufficient ambiguity between the RAMP level (some obscure mid-level where passengers apparently do not want to be) and the CONCOURSE level (where you can board your plane) to justify the addition of the hardware-equivalent of software's floating tool tips. Of course, these tool tips are completely invisible to blind folks who are likely to all be congregating on that floor marked with the star R on it.

    So, there is evidence that designers of hardware (and certainly software) are not paying attention to important matters.

    Now back to the original question -- why is great UI so hard to achieve? While a number of factors impact the ultimate outcome, I would suggest the most important influencer is training. It seems that most developers and designers creating interfaces for human consumption simply lack a small bit of knowledge that could make a huge difference.

    How big of a difference? Well, for starters, let's go back to the gas station where I bought fuel this morning. Swiping my credit card, I'm presented with a message on screen, that looks like this:

    Is this a debit card?

    Of course I am unable to proceed until the question is answered. I happen to be using a credit card, not a debit card, so I know the answer is no. However it is not immediately clear how I'm supposed to communicate this status to the machine.

    So next I move my gaze down to scan the keypad. After reading labels on a half-dozen buttons, I find the buttons labeled Yes and No at the bottom-right of the keypad (much farther away from the message than they need to be). I should point out that the question (e.g., "debit card?") changes from station to station -- sometimes the machine wants to know if I'm using a credit card, and sometimes the machine asks me to find buttons labeled Credit and Debit and then press the right one. Remembering that the question this time was asking if I was using a debit card, I click the No button, and return my gaze to the screen above, to see if I am now permitted to put fuel in my vehicle.

    All told, this sucks up about ten seconds of life each time I use my card. And not only at gas stations, but grocery stores and many other places of business. Every time I try to give my money to the merchants, they just try to slow me down. This is not in their best interest, nor is it in mine.

    Poorly-designed UI acts as a frictional force against the economy. How much does it cost? Well, let's start multiplying those ten seconds out across all the millions of transactions occurring every day across all of these machines, and you have a picture of an amazing amount of time wasted. Multiply that time by average salary of those affected and you have a way to estimate the cost of this design choice.

    But why ask the debit card question in the first place? Personally, I never carry any debit cards. For me, the answer will always be the same. Well, it would always be the same if the questions were always the same. And surely we live in a world where technology can identify on some end (the gas station, the bank, etc) which way my card swings.

    So, bad UI surrounds and the reason for this failure may simply be lack of training. And I'm betting when you first saw the question you were thinking it was something else. :-)

    The test for this assertion is simple. Follow the series, get the training, and watch how dramatically that improves your ability to design great interfaces.

    In the next post, we'll dive into clarity.

  • The Essence of Great UI - An Overview

    I've decided to spend some time doing a brain dump of everything I know about great user experiences. Here's the first of what I hope will be a fun and inspiring journey. I also expect this series will serve as a replacement for the book on great UI that I'm unlikely to ever write....

    The most important thing to start with is the knowledge that great UI is all about three things:

    • Clarity

    • Efficiency

    • Discoverability

    Clarity is the ease of understanding presented information.

    Efficiency is the ease of control and movement through the data. There are obvious physical components to this, and there are not-so-obvious mental components as well.

    Discoverability is the ease of finding and understanding that which lies below the surface.

    So the challenge to creating a great UI is to maximize all three of these. However, this is rarely easy to do, as there are many paths we might take, and natural tensions that exist along those paths.

    In future posts, I'll show how to measure efficiency, clarity, and discoverability, and talk about interesting ways we can improve these elements of the user experience. And as always, I encourage interaction and ideas from you. Feel free to post a comment below, or email me directly at markm at the Dev Express domain.

    No series on great UI would be complete without a discussion about the value of great UI. And so in future posts we'll show how to measure the cost of poor UI. Today, I'll just leave you with an observation you may find interesting. There appear to be correlations among the following:

    CorrelationBetweenGreatUIandIncome2

    In the next post, we'll look at why great UI is so hard to achieve.

More Posts Next page »
Copyright © 1998-2009 Developer Express Inc.
ALL RIGHTS RESERVED