Rory Becker - DevExpress CodeRush Blog
  • New CodeRush Community Plugin – DX_GenerateProxy

    DX_GenerateProxy

    Generates a new Proxy class P based on source class S

    What?

    What this amounts to is a new class P which is given properties and methods matching the public ones that are possessed by S.
    When methods or properties of S are called their implementation defers to the instance of P held internally.

    Why?

    • I’m beginning to prefer working in terms of interfaces where possible. I like to mock interfaces rather than classes where possible.
    • I don’t like to modify generated client-side web-service code. This therefore means that I don’t like to extract interfaces from said code.

    The solution to this problem is to wrap the client-side web-service code in a proxy of my own from which I can extract an interface without having to alter the client-side web-service itself..

    So given a web-service (W1), I can create a proxy (W1_Proxy) with all the same methods and properties as the original class. I can extract an interface from W1_Proxy and write my client-side code in terms of this interface. During testing I can implement this interface a second time in a test class (or more likely I can mock the interface), and pass this to the same code.

    This gives me

    • Client code that doesn’t depend on a specific implementation of a service
    • Client code Tests that don’t depend on the web-service in order to run and prove my code works.
    • A good feeling of having done things the right way.

    Limitations

    Currently this CodeProvider only acts on Class declarations for which you have source code. a Later revision will add a facility to generate a proxy for compiled types.

    Example

    Let’s start with the following code…

    GenerateProxyClass_Before

    Place the caret on the name of the class and then press your CodeRush Refactor key

    GenerateProxyClassSmartTagMenuItem

    …and the following code will be generated for you…

    GenerateProxyClass_After

    Download DX_GenerateProxy

  • New CodeRush Community Plugin – DX_InterfaceNav

    DX_InterfaceNav

    Provides a new Navigation entry (“To Implementor”) which navigates to implementations of an interface.

    The default Navigate shortcut is Ctrl+Alt+N

    You can use this plugin to navigate to Implementations of an Interface from …

    • Instance Reference -  From reference to a variable who’s type is either ISomeInterface or descends from same.
    • Class Declarations -  From the declaration of a class. Caret on class name.

    DX_InterfaceNavExample2

    You can also use this it to Implementations of Interface Members from…

    • Method Reference -  From references to a property or method on a variable who’s type is either ISomeInterface or descends from same.
    • Variable Reference - From references to a Parameter who’s type is either ISomeInterface or descends from same.

    DX_InterfaceNavExample1

    Work will continue on this plugin to provide additional navigations.

    Download DX_InterfaceNav

  • New CodeRush Community Plugin - DX_ConvertToTryParse

    DX_ConvertToTryParse

    This new plugin provides a new item for the Code menu which converts…

    ConvertToTryParseBefore_thumb[5]

    …into…

    ConvertToTryParseAfter_thumb[2]

    There is a small limitation in this version. The new variable introduced (“Success”) is currently hardcoded and may clash with an existing variable. I’ll fix that in an update. I just wanted to get this out there for now.

    Download DX_ConvertToTryParse

  • New CodeRush Community Plugin – DX_RedundantAssignment

    Over the last few weeks I’ve returned to writing plugins for a bit, and I think some of them have reached the point where they might be useful for people beyond myself.
    This post, and the next few that follow it, are intended to just put these plugins out there and see what people think.

    Feel free to post comments and feedback.

    DX_RedundantAssignment

    This first plugin is an example of how to build a simple Refactoring and CodeIssue and link them together.

    This CodeIssue will alert you if you are assigning a variable to itself. Further, the CodeIssue provides a link to a Refactoring that will remove the assignment from your code altogether.

    RemoveRedundantAssignmentCS_thumb2_t

    The refactoring is of course available in it’s own right via your CodeRush\Refactor Key

    RemoveRedundantAssignmentVBRefactori

    Download DX_RedundantAssignment

  • What is a Dynamic list?

    Question: What is a DXCore Dynamic list?

    Simple Answer: A named dictionary<string, string> with associated Name, Description and Variable.

    OptionsPageTreeDynamicListsYou can locate the dynamic lists through the options screen.

    It’s an advanced page, found at Core\Dynamic Lists

    Note: The Dynamic lists options page is one of those pages, whose content is language based. There are lists for VB.net and C'# as well as quite a few *neutral* lists.

    As stated above, each list is really a named dictionary<string, string>. 

    Consider the following  list of dictionary items…

    Key Value
    s System.String
    i System.Int32
    ds System.Data.DataSet

    Imagine that this list was called System Types an was associated with a variable called Type.

    Now imagine another list….

    Key Value
    mbc MyBusinessClass
    mobc MyOtherBusinessClass
    mnst MyVerySpecialType

    …this second list is called Custom Types and is also associated with a variable called Type.

    Now let’s a imagine a CodeRush template called v?type? whose definition is…

    -------------------------------------------------------------
    Private «?Get(Type)» «Caret»MyVariable«BlockAnchor»;
    -------------------------------------------------------------

    What we have here, is a template that can be triggered by a user typing the letter v, followed by any of the items on the left side of either of the 2 lists.

    Therefore the following are all valid triggers for the template:

    Template Trigger Expansion
    vs<space> private System.String MyVariable;
    vi<space> private System.Int32 MyVariable;
    vds<space> private System.Data.DataSet MyVariable;
    vmbc<space> private MyBusinessClass MyVariable;
    vmobc<space> private MyOtherBusinessClass MyVariable;
    vmvst<space> private MyVerySpecialType MyVariable;

    Note: A dynamic list can be flagged as containing .Net types. In which case it will remove any unnecessary name-spacing at expansion time, and return only the core type. This would mean returning String instead of System.String. This, I think you’ll agree, is much more aesthetic.

    For those that haven’t spotted it, the example lists I mentioned for this demonstration are standard dynamic lists that already ship with CodeRush. Additonally the v?type? template is also a real template (Although the real version is a mite more complicated to allow for additional scenarios).

    The first list (System Types) contains mappings for 68 of the more commonly used types in the .Net framework as well as 3 special mappings I’ll explain in a moment.
    The second list (Custom Types) is initially empty when shipped but can be added to by you the user.

    What about my types?UseTypeInTemplates

    If you come across a business class you wish to add to this list (making it accessible by any template that uses the ?type? syntax and variable) then you can right click it and use the Use Type in Templates menu item. This will ask you what abbreviation you’d like to use for the class in question and then add it to the Custom Types list.

    Special Values

    The System Types list also contains 3 additional items.

    Key Value
    \ «?Paste»
    / «?Type»
    ? «?ReturnType»
     
    This gives us a clue that the value n these lists, need not be entirely literal. indeed they can contain StringProviders as seen in the above examples.
     
    In this case…
    … v\<space> will yield a variable whose type is pasted from the clipboard.
    … v/<space> will yield a variable whose type is the same as the type whose code enclosed the caret.
    … v?<space> will yield a variable whose type is the same as the current method’s return type.
     
    These shortcuts can obviously also save a lot of typing.

    So what’s dynamic about a dynamic list

    A Dynamic list is a list of mappings typically from shorter more terse strings to larger strings. The dynamic part, is that you can choose to add items to the list without informing anything that is referencing it.

    This means that instead of constructing one template for each potential element in your list, you can construct a single template for the list itself, and have CodeRush do the hard work for you. Additionally if you ever choose to add to the list for any reason, you won’t have to amend the template.

    Finally the same list can be reused in many many templates. (for example in CodeRush we ship v?type?, m?type?, p?type?, a?type? and r?type? )

    When you add a business type to the Custom Types list, this new class is available to all those templates that make use of the Type variable with no extra work on your part.

    Now that’s a big win.

    In an upcoming blogpost, I’ll show you how to build some additional functionality for CodeRush using a new custom dynamic list which we’ll create for the purpose.

  • CodeRush Template – Creating Virtual Methods

    CodeRush provides many templates for lots of different purposes. Of course you can’t cover every eventuality out of the box. So instead we built a system which allows you to build a solution of your own when you need to.

    Recently I was asked if there was a quick way to create a public virtual method.

    I did a quick search and discovered that there did not appear to be any pre-built in template that did this.

    However, as I’ve said before, building this sort of thing is pretty easy. So I decided to prove it and do the leg work to build my own.

    There are 2 parts to this: Naming and Implementation.

    Naming

    Well it turns out the naming is the hard part.

    It’s always good to have your templates named something which suggests the purpose of the template. Failing that, it should be closely related. ie There should be some logical link.

    Additionally it’s great if you can use as few keys as possible. Short of using mind control, and therefore zero keys, ideally we’ll settle for one… But which one?

    To this end I asked myself what the appropriate name for a template that produced virtual methods would be…

    • V – Already used for Variables
    • I  - Already used for Interfaces
    • R - Already used for Readonly properties
    • T - Already used for Types
    • U - Unused
    • A - Already used for auto-Implemented properties.
    • L – Unused

    Well that didn’t leave much of a choice. U or L.

    I chose L.

    Implementation

    Next up we need to create 2 templates which will provide us with the output we need.

    The original request was to produce a template which would output a public virtual method. The example given showed a void proc, but I figured it would be better to also provide the ability to produce methods that returned various types like our other dynamic templates.

    So I decided to base my templates on the m<space> and m?Type?<space> templates. This allows us to pass in any of the usual type params, or miss that out entirely and just emit a void proc as per the original example.

    If you’re unfamiliar with creating templates, or would like a quick refresher, then it’s probably worth reviewing my previous post on Template Creation Basics

    The Templates

    I created the following templates:

    Name: l?Type?
    Context: Editor\Code\InClass
    Expansion:
    -------------------------------------------------------------
    public virtual «:#MethodSignature#»«:#MethodBody#»
    -------------------------------------------------------------


    ...then a second template...
    Name: l
    Context: Editor\Code\InClass
    Expansion:
    -------------------------------------------------------------
    «Set(Type,void)»«:l?Type?»
    -------------------------------------------------------------

    Note: The contexts indicated above are a little simplistic. In reality, we should base the context from the m?Type? template.
    This would be something like: ((InClass or InStruct) and OnEmptyLine) but not (InComment or InMethod or InPreprocessorDirective or InProperty or InString)

    How does this work?

    In this section I'm going to explain a little of the detail about how these templates work with one another. If you don’t care about this, then feel free to skip ahead. There’s nothing vital here, but for those who are interested in creating their own templates, deconstructing an existing set can be useful.

    Let’s start with the l?Type? template which you added above:

    This template emits the phrase “public virtual “ and then defers to 2 other templates (#MethodSignature# and #MethodBody#) for the rest of it’s functionality.

    Note: Templates whose names are surrounded by # (pound signs or hash marks depending on your point of view) are called system templates. This is not because the have special access to system functionality or anything. Instead it’s because that naming convention is judged to make them unlikely to be called by a user directly and therefore are assumed to be in use solely by other templates (ie the system).

    If you look, you’ll find that each of these has their own expansions.

    #MethodSignature#

    Template#MethodSignature#

    #MethodBody#

    Template#MethodBody#

    Additionally #MethodSignature# also calls a level deeper into the #MethodParameters# template...

    #MethodParameters#

    Template#MethodParameters#

    This style of aliasing, is like calling a method. It allows you to extract a piece of a template and reuse it from as many places as you like. In this case we get to reuse functionality from templates that the DevTeam already created.

    If we expand  these aliases in the same way that CodeRush would, you can see what we would have had to type without this facility.

    TemplateLTypeAliasesExpanded

    So how does this work?

    Well this template does 6 things

    1. The literal phrase “public virtual” is emitted into the editor.
    2. The «?Get(Type)» StringProvider emits a reference to the Type passed in the trigger string. (String,int32, Dataset etc)
    3. The MethodName is wrapped in a «Field» in order to suggest a suitable edit point.
    4. This field is wrapped in  «Caret» and «BlockAnchor» pair indicating that Studio should select this text.
    5. A further «Field» is created to allow the entry of any method parameters.
    6. A method body stub is emitted. This contains a «FinalTarget» TextCommand within it represents the position to move the caret to when both fields have been entered.

    In the case of the 2nd template, we use «Set(Type,void)» in order to pre-set the type to void (ie no return type) and the call the 1st template via «:l?Type?». This passes the void type to the 1st template causing it to expand a method stub which returns no value.

    Note: To add even more functionality, you could create duplicate versions of these templates that omit the “#MethodBody#” aliases and the “public” keyword, making said duplicates suitable for use inside of interfaces. Of course the contexts of these duplicates should also be altered to only work inside of interfaces, but I’m sure you can see how quickly this could be achieved.

    Usage

    Well the usage of the template is quite simple. Position the caret somewhere sensible within a class or structure…

    Type ls<space>

    … and you will be rewarded with the stub of a public virtual method that returns a string. Alter it’s name and hit enter. Your caret jumps within the parenthesis ready for you to expand templates to.

    Additionally you can use…

    l<space>

    …to omit a return type and have the system emit a void proc instead.

    Conclusion

    As you can see, there’s not much to each of the parts involved in these templates. The power instead, is in the flexibility of each part, and the combinations in which they can be used. And so we have gone from feature request to fully developed feature in no more that 15 minutes.

  • CodeRush Plugin – TabNav

    Today I was navigating some legacy VB.Net code, and found myself wishing that I could quickly navigate from the top of a method to the bottom or vice-versa. Naturally my first thought was to write a plugin to add this capability.

    Seconds later, without knowing quite how I got there (Now that’s real muscle memory) I was starring at the default code of a new CodeRush plugin in VS.

    Note: Yes I realise that C# already has this functionality (Ctrl+]), but I wanted it in VB.Net as well.

    And so now I’ll show you how easy it was to build this exact plugin.

    Let’s build it

    This plugin is another example of a Simple Action Plugin and assumes that you already know how to Create a Plugin Project and add an Action

    The specifics of this plugin require 3 steps:

    • Set the Action’s ActionName property to “TabNav”.
    • Handle the CheckAvailability event.
    • Handle Execute event.

    Since the first step is only setting a property, we’ll concentrate on the CheckAvailability and Execute events.

    The CheckAvailability Event

    The purpose of this event, is to give us a place to decide if our action should be available, given the state of the code and our position within it.

    In our case, we require have 3 requirements:

    • The caret must be positioned on an element which has a block construct.
    • The caret must not be positioned on the name of the element (if any).
    • The caret must not be positioned on the type of the element (if any).

    To explain a little….

    • We require a block construct, because otherwise our action would be allowed to fire for primitives and statements etc. To navigate from start to end has no real meaning in these cases.
    • We explicitly do not allow our action to fire if we’re on the Name or Type of an element, because we don’t want to clash with the already wonderful TabToNextReference

    If all of these requirements are met, then we set ea.Available to true.

    TabNavCheckAvailability

    The CheckAvailability event is fired whenever the DXCore wishes to determine if the Action should be available. Because of this, our Execute event can rely on the fact that these prerequisites have been met, and get on with it’s main function with no need to double check them.

    The Execute Event

    This event is raised when the user elects to trigger the action. As noted before, the CheckAvailability event will have already been raised, and by virtue of having reached the execute event, we can assume that all requirements were met.

    Our plugin basically requires that we jump from one line of code, to another.

    We determine which line we’re on and instruct the DXCore to move the caret to the other. As an added bonus we jump to the first non-space character of that line.

    TabNavExecute

    There are 3 other methods in the code for this plugin. The PosOfFirstNonSpaceChar function is hardly worth mentioning. It’s a simple iteration that determines the (1-based) index of the first non-space character on a given line.

    The other 2 functions (shown below) determine if the caret is positioned on either the Name or Type of an element.

    TabNavUtilities

    Using TabNav

    This plugin will compile and run just fine as it is, but there is one final step you must take before you can see it in action.

    The TabNav action must be bound to a key. As you might have gathered, I recommend you bind the TabNav command to the {Tab} key

    At this point you should be able to Tab from Class –> End Class or back again. Additionally the same functionality should work for Namespaces, Methods, If statements, Do While loops and many others.

    Compatibility

    You might have noticed that nothing in the code so far, specifies any sort of language compatibility. This is because we’re working with abstract language constructs. So by default, this plugin will work in any imperative language supported by the DXCore.

    As previously noted however, this functionality is already supported by the VS Team for brace-based languages. The Ctrl+] keystroke will jump you between a function’s opening and closing brace. If you wish to rebind this, the command name is “Edit.GotoBrace”.

    Personally I think my use of {Tab} is much more intuitive, especially considering the beauty that is CodeRush’s TabToNextReference

    Whilst developing this plugin I learned that there are a few edge cases for the C# language that simply don’t apply for VB.Net. Chief among these, is the fact that the block start line is not always the same line as the Element start line. There are simple ways around this but since C# doesn’t need this feature, I elected to disable it in languages other than VB.Net.  In order to do that you can use this additional code in the CheckAvailability event:

    TabNavCheckAvailabilityAdditional

    In any case the plugin and it’s source code is available from the community plugin site

    So download, install and enjoy your new found freedom Smile

  • Merging CodeRush Templates (via Export and Import)

    When a new version of CodeRush is released, it’s quite often the case that there are new templates included with it.

    So why when you’ve completed the install, are these templates not always immediately available?

    Well put simply, it’s because we don’t want to damage or break any Template customizations that you might have created yourself.

    As you are no doubt aware by now, CodeRush is one of the most configurable products on the market. In this spirit, we allow you to add your own Templates or even customise the ones we offer you out of the box. If we were to overwrite these changes each time we installed, we’d upset people pretty quickly.

    Since we don’t like to upset people, we choose instead to not overwrite your templates with our own stuff unless you ask us to.

    This post is designed to show you how to merge your own custom Templates, with any new ones we might be shipping in a new release.

    Step 0 – Always work within a ‘Custom’ folder

    Yes there’s a step zero. This isn’t so much a step, rather more of a mind-set for when you’re creating templates of your own. We don’t force you to create templates in any particular way, but we do suggest that when you create new templates, that you do so inside of a new top level folder called ‘Custom’. By placing your Templates in this folder you are creating a single parent for all of your templates which will greatly ease the management of them in situations like merging.

    Step 1 - Export your custom TemplatesTemplateContextMenu

    • Open up the Templates options page (Ctrl+Shift+Alt+OEditor\Templates)
    • Right-click the Custom folder (The one you always put your custom templates in) and choose Export Folder. Save the resultant file somewhere safe.
    • Repeat for each language where you have created Templates of your own.

    Step 2  - Force CodeRush to rebuild your templates from defaults

    • Choose DevExpress\About
    • Click Settings
    • Dig into the Editor\Templates folder.
    • Delete (or move if you’re feeling more cautious) the files in this folder.
    • Switch back to VS
    • Return to the Templates options page again
      • Note: All of the templates will have been rebuilt from (new) defaults (without your custom templates)

    Step 3 – Reimport your Custom Templates

    • Select in turn each language for which you exported a file in step 1.
      • Right-click the template tree and pick Import Templates
      • Select the previously exported file which pertains to your currently selected language.
      • Click Ok and note how the Custom folder returns to the template tree.
    • Repeat for each language

    You have now merged the new templates with your own customizations, and are done.

    You should be able to see your own custom templates, and any new ones shipped with the most recent version of CodeRush.

  • AlexS rocks the CodeRush Tips n Tricks

    You’ve got to love this: http://www.skorkin.com is a site dedicated to Tips and Tricks relating to CodeRush, Refactor! and The DXCore.

    The blog currently contains 130 different tips on the use of the DevExpress IDE Tools, with more being added all the time.

    There’s a great selection of sub-categories as well so you can quickly find what you’re looking for.

    Oh and did I mention? Alex is one of the CodeRush Devs, so he knows exactly what he’s talking about.

    SkorkinDotCom

  • CodeRush – Common TextCommands

    TextCommands

    Compared to StringProviders, TextCommands are rather more complicated to explain. This is because they are used for a more diverse set of tasks.

    To this end I will explain several of the more commonly used TextCommands and show you exactly how they are used.

    They don’t inject text in the location they occupy. Instead their location is typically used as a reference for some other sort of operation.

    As always, we’ll start of simply.

    «Caret» and «BlockAnchor»

    The «Caret» TextCommand is exactly what it sounds like. It indicates where your Caret (The blinky thing, that emits text when you type) will be placed after your template has been expanded.

    The «BlockAnchor» TextCommand is an optional counterpart to the «Caret». If used together, text placed between them will be selected once the template has expanded.

    So if you wanted to write a simple C# class template with no constructor you could do so using the following text:

    TemplateClassCaretBlockAnchor

    This would emit the basic text and would select the phrase “DefaultClassName”

    TemplateClassCaretBlockAnchorExpanded

    Markers

    You can enhance the template above with the use of a «Marker» TextCommand. We’ll leave a full description of markers until another time, suffice to say that a marker is like a breadcrumb. You (or indeed templates and other features) can leave a trail of them, and then later you can jump back to the most recent one, and pick it up by pressing Esc.

    Thus if we amend our previous template like so…

    TemplateClassMarker

    TemplateClassMarkerExpanded

    … then the template will emit a small blue triangle called a Marker. When we expand the Template, and overtype the selected area, we can then hit Esc and the caret will jump down to the indicated area and ‘collect’ the Marker.

    It’s worth noting that this basic (blue) marker will also disappear if the line it’s on is altered. If you’d like to produce one that does not disappear under these circumstances, than you should use the alternative «HardMarker» TextCommand. This type of Marker will only disappear if it is ‘collected’.

    Links

    The «Link» TextCommand is used in groups of 2 or more, to connect identical pieces of text to each other, and to keep them the same if one of them is edited.

    The classical example of this, is seen through the C# version of the c<space> template.

    The creators of C# took the decision that constructors should be named after classes they exist within. So if you create a C# class called MyVerySpecialClassWhichDoesSomethingVeryClever, then you have to use this (rather lengthy) name for any constructors that you create. The downside of this, is that you’ll have to do a lot more typing than if you were able to use a simple keyword for the same task.

    By using a couple of «Link» TextCommands, we can link the name of the class to that of the constructor, ensuring that the actual naming need only be done once.

    TemplateClassLink

    In this manner, the class name and the constructor name are linked together at the moment of expansion, and as one changes, so will the other.

     TemplateClassLinkExpanded

    A Link TextCommand links itself to all other Links that contain the same text. This allows the creator of the template, to link several pieces of text together.

    The user may also navigate between linked items through the use of either Tab or Shift+Tab.

    Check out this template for creating properties (of the non auto-implemented variety)

    TemplatePropertyMultipleLinks

    It links together 4 separate instances of the phrase “MyVariable”. When one is altered, all are altered. This enables the property, it’s underlying field and the 2 references to the field, to be renamed as a unit.

    TemplatePropertyMultipleLinksExpanded

    I think you’ll agree that this is very useful indeed.

    Other Types of Link

    The «Link» TextCommand accepts only characters that are valid in an identifier. ie alphanumeric characters or an underscore (‘_’).  If you wish to create links which allow additional characters within them, consider the use of either a «TypeLink» or a «TextLink».

    A «TypeLink» can accept any character which is deemed valid as a part of a Type, therefore it will also accept periods ('.'), commas (','), spaces, angle brackets ('<>') in C#, square brackets ('[]') in C# and parentheses ('()') in VB.

    Finally, the least restrictive of the link types is the «TextLink». If you require the user of your Template to be able to type characters not listed above, then you should consider using a «TextLink» TextCommand instead.

    So far we’ve shown Templates which highlight some of their emitted text, and allow the user to make amendments to it. Further we have shown how bits of text can be linked together so that alterations to one, will affect others.

    These links can be very useful, but what if we want the user to be able to make several such edits once the expansion of the template has occurred? Well you can place as many sets of links within a Template as you like, but your user will have to navigate between them on their own. By themselves, links provide no method for navigation to other link sets.

    However we do have fields….

    Fields

    Each «Field» TextCommand in a Template represents a distinct point of data entry. Upon expansion, the caret is deposited, in the first «Field» and as usual the user is free to modify the resulting text or indeed move elsewhere. If the user hits enter whilst the caret within a field, the field will be accepted, will disappear and the caret will jump to the next field.

    A simple example of the use of fields is the following template designed for creating auto-implemented properties.

    TemplateAutoPropertyGeneral

    The first field is positioned to allow the user to indicate the Type of the property. The second is to allow for the Name.

    TemplateAutoPropertyGeneralExpanded

    If the example given doesn’t seem so useful, consider the following custom Template, used in the creation of my own CodeRush plugins.

    TemplateNewActionPartialCS

    When expanded this Template provides the following output:

    TemplateNewActionPartialCSExpanded

    In this example we see a few techniques being used together. We have 3 fields, one of which is linked to 8 separate other locations via links. At this stage, you may or may not know much about plugin creation, but you can clearly see that there’s a whole lot of typing to be saved using this template. As for the previously unmentioned «FieldStart» and «FieldEnd», these are simply another form of the «Field» TextCommand.

    So why do we need another form of the «Field» TextCommand? Well it’s for times like the one demonstrated, when you need to wrap other TextCommands in a field. If you recall, TextCommands don’t return a result in the same way as StringProviders do, and the standard Field TextCommand requires a parameter. The «FieldStart» and «FieldEnd» TextCommands do not require such a parameter, instead acquiring the data they need from the text rendered between them.

    The last Template in this group is «FinalTarget». This TextCommand works within the context of a template already using 1 or more fields. It acts as the final field in a sequence. The difference being, that it is a point rather than a range and it requires no parameter. Use this TextCommand to indicate where the caret should jump to when all fields have been filled.

    And Finally

    The last 2 TextCommands I’d like to mention in this post are «AddAssemblyReference» and «AddNamespace». They perform pretty much as you’d expect, acting on the periphery of any function they supplement.

    «AddAssemblyReference» takes a single parameter which indicates the name of the reference to add. This results in no direct changes to the active TextDocument, but as you might imagine, the project to which it is attached receives a minor alteration adding a reference to the passed assembly.

    «AddNamespace» likewise takes a single parameter. This time indicating a single namespace which should be referenced by this file via an “Imports” or “Using” directive as appropriate. Said directive is added at the top of the file.

    ..and that about wraps it up for this post.

    We’ve covered the ins and outs of 13 separate TextCommands. That’s a little over 20% of the 61 TextCommands in my copy of CodeRush. As before this should be enough to get your feet wet, and also help you to understand a much larger quantity of the shipping templates that use them.

2 3 4 5 6 7 8
9
10 11
LIVE CHAT

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 info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. 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-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners