Rory Becker - DevExpress CodeRush Blog

September 2011 - Posts

  • New Plugin: CR_MultiSelect

    We’re all familiar with how text selection works in windows.

    You click and drag, from one end of some Text, to the other. Typically this text is highlighted by inverting the foreground and background colours to give you an easy way to see what is ‘selected’. Alternatively you may use the shift key in conjunction with one or more of several navigation keys (left, right, up, down etc)

    Of course using CodeRush you have even more options for defining your selection.

    Once text is selected, you choose what you’d like to do with that text:

    • You can click elsewhere to cancel the selection.
    • You can select some alternate text.
    • You can use the selection as a part of some operation.
    • Replace the selected text by simply typing over it.
    • Cut or Copy the selection to the clipboard

    CodeRush Post-Selection Operations

    CodeRush naturally gives you more options for using any text you may have on the clipboard.

    And many others.

    SideNote: A little known CodeRush clipboard feature, is the use of the \ character when a CodeRush template requires a type mnemonic. This will check the clipboard for a type and use that in lieu of a more explicitly specified type mnemonic. For example ps<space> yields a property of type string. However p\<space> yields a property who’s type is the same as that held on the clipboard.

    So now let’s consider what life might be like if we could have “multiple” concurrent selections.

    Let that sink in for a minute.

    Multiple. Concurrent. Selections

    So what would that be like? Well you could select some text, and then select some other text elsewhere without loosing the first selection. This process could continue indefinitely adding as many selections to the list as we like. If many selections are to be involved, it would probably be prudent to have a function to remove the most recent selection (an MultiSelectUndo of sorts). This would allow you to correct a poorly added selection in case a mistake was made, allowing you to add a different selection. A corresponding MultiSelectRedo would not seem unreasonable. Once a multiselection was established, the clipboard operations could be used to cut, copy and paste this text like any other text.

    How might you use such a feature?

    Imagine that you have a class (OldCalculator) that you’re not very happy with. You’re pretty sure you can do better. You think it’d be a good idea to start from scratch. Perhaps you’re going to channel Mark Miller and create UltraMegaAwesomeCalculator Winking smile

    You create a new class (c<space> and type your new classname).

    Your next thought might be, that while some of the old code was appalling, there were parts of it that weren’t so bad. Given a simple way to do so, you’d love to grab a copy of the right pieces and deposit them into UltraMegaAwesomeCalculator. However the good parts are spread about in different parts of OldCalculator.

    If you’re going to go and get them and copy them into this class, it’s going to take a lot of context switching and a lot of keystrokes to get the job done.

    With multiple selection, you could select a couple of private members, a method or 2 and a subclass which you found to be of good quality. You could then copy those with a single keystroke and paste them into your new class.

    Well that’s exactly what CR_MultiSelect does.

    …and that’s just the tip of the proverbial iceberg.

    The basic version of CR_MultiSelect includes functions for MultiSelectAdd and MultiSelectClear as well as overridden versions of Cut, Copy and Paste and the suggested MultiSelectUndo and MultiSelectRedo

    If you have a full keyboard I suggest using Ctrl+NumEnter and Ctrl+NumDel on your numeric keypad. Likewise if you’d like to use either MultiSelectUndo or MultiSelectRedo, I suggest assigning these to Ctrl+NumMinus and Ctrl+NumPlus

    Details on assigning shortcuts may be found here


    Imagine the simple scenario of copying 2 fields and a method from Class1 to Class2, let’s compare workflows:

    Single Selection

    Multi Selection

    • Move to Class1
    • Click start of Field1
    • Drag to end of Field1
    • Copy
    • Move to Class2
    • Paste
    • Move to Class1
    • Click start of Field2
    • Drag to end of Field2
    • Copy
    • Move To Class2
    • Paste
    • Move to Class1
    • Click start of Method1
    • Drag to end of Method1
    • Copy
    • Move to Class2
    • Paste


    • Move to Class1
    • Click start of Field1
    • Add Selection (Autoexpands selection to Field1)
    • Click start of Field2
    • Add Selection  (Autoexpands selection to Field2)
    • Click start of Method1
    • Add Selection (Autoexpands selection to Method1)
    • Move to Class2
    • Paste (All items pasted at once)

    18 operations

    9 operations

    That’s 50% less operations and a whole lot less context switching and visual disorientation.


    Here is a simpler and more visual version of the same:

    Note: I recorded this demo on laptop without a Numeric keypad, so I bound MultiSelectAdd to Alt+A (I did not need the Data Keyboard) and MultiSelectClear to Alt+C


    Note: In the above demo, there wasn’t even a need for me to drag and select the fields. CodeRush automatically expanded the selection around the logical member (Using Selection Increase and Decrease in a similar way to SmartCut and SmartCopy) as a part of the MultiSelectAdd operation.

    Integrated Paste

    Just to ice the cake, and also give an idea of where we can take this sort of feature in the future, we decided to implement MultiSelectIntegratedPaste.

    Since we are the ones placing information on the clipboard, we can also store some of the DXCore metadata with it, and then make use of that information later. So when you use MultiSelectIntegratedPaste instead of normal paste, and assuming that you’re pasting class members  into a class, we’ll sort those members by type and emit them in that order instead (Method, Property, Event, Variable, Other)

    The Future…

    We think that this functionality is so useful, that we’re going to push Multi Selection down into the DXCore. Once this is done, the MultiSelect service will be available to any plugin that sits on the DXCore, allowing anyone writing plugins to use this functionality. We can begin building on it in the main CodeRush feature set, and so can you.

    In the mean time, feel free to download this plugin and have a play.

    Note: The plugin mentioned in this post was created during a CodeRush Feature Workshop (Part1, Part2).

  • Community Callout: CodePlugIn_INotifyPropertyChanged

    Yes, that ‘s right we’ve got another community plugin to shine a light on.

    Brian Noyes has created CodePlugIn_INotifyPropertyChanged

    The idea is to take a plain ordinary property, and augment it with additional code to support the INotifyPropertyChanged interface.

    This is done by providing 2 additional CodeProviders (Convert to INPC Property and Convert to INPC Property Base Class Call) which are available from the Code menu when your caret is on a property.

    Convert to INPC Property will happily change this…


    …into this…


    If your class already inherits from NotificationObject then you’ll be able to use Convert to INPC Property Base Class Call to upgrade it from this…


    …into this…


    For full details see The Wiki Page.

  • New Plugin: CR_ProjectReferenceDefaults

    This week’s CodeRush Feature Workshop saw the creation of a plugin to manage the values given to properties of a reference, when it is first added to your project.


    When you add a new reference to a project…

    For Non GAC assemblies, Copy Local typically defaults to true with Specific Version defaulting to false.
    For GAC Assemblies, Copy Local typically defaults to false with Specific Version defaulting to true.

    However this is not always the effect you’re looking for.
    For example. I mostly code plugins on my Laptop and would prefer…

    For Non GAC assemblies, Copy Local should default to true with Specific Version defaulting to true.
    For GAC Assemblies, Copy Local should default to false with Specific Version defaulting to false.

    These are clearly personal preferences and everyone will have their opinions.

    CR_ProjectReferenceDefaults allows you to change the default values of these properties, so that all new references take on the values you decide.


    Note: This version does not provide for differences between GAC and NonGAC assemblies and chooses to treat them the same way. However the code is relatively simply and should be very easy to extend.


    Configuration is simple.

    • Visit the Options Screen (DevExpress\Options or Ctrl+Shift+Alt+O)
    • Locate the Project\Default Reference Properties page.
    • Adjust options to suit and click Ok.

    Note that each of the 2 options, can be set to any of 3 values. The default value of these is indeterminate, which means that no action will be taken for this property when the reference is added. The other values (checked and cleared) represent the true and false states that will otherwise be assigned to the property in question.



    Usage is automatic. Once the plugin is installed and configured, adding a reference will trigger a post add operation, which will alter the properties as configured.

    So what are you waiting for? Go download CR_ProjectReferenceDefaults now.


Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at or call us at +1 (818) 844-3383


DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, Delphi, HTML5 or iOS & Android development. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2018 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners