.NET Tools
Essential productivity kit for .NET and game developers
XAML Support in ReSharper 8
With the arrival of WinRT, it has become clear that XAML is here to stay, whether you’re writing Windows Store apps, Windows Phone apps or good old WPF desktop apps. As a result, ReSharper continues its mission to help developers deal with the verbosity of XAML. The following outlines the various XAML-related features present in ReSharper 8.
Code Completion
The fundamental operation of XAML code completion has been refined to make entity creation a simple, painless process. You can now enter the name of a type (or even a camelHumps shorthand) without either having to use the opening <
symbol or the namespace prefix:
For styles without a target type, we now offer automatic completion so the user can pick a type from a particular namespace:
Also, ReSharper now provides code completion in x:Shared
and xml:space
attributes:
Style Inspections and Fixes
There are plenty of new inspections and corresponding fixes in ReSharper 8. Here’s a selection of a few of them related to control styling.
In the case where a TargetType
is defined on a style setter, ReSharper will detect extraneous use of type qualifiers and will offer a fix:
A similar fix is offered in the rare case where a redundant qualifier appears before the name of a tag:
If a setter redefines something from a style it’s based on with a new value, ReSharper shows a gutter mark that allows navigation to the base setter:
However, if a setter redefines it with the same value, ReSharper flags it as redundant and offers to remove it completely:
As soon as you apply a style explicitly to a control and then use any of the styles that have already been defined, ReSharper flags them as redundant:
ReSharper uses very rigorous analysis when looking for redundancies. For example, with the text block’s Tag
defined having the value of “Some text”, ReSharper shows the following as a redundant element:
ReSharper is smart enough to handle cases like the one above with its careful attention to ways in which properties are expressed, the ordering of the properties in composite objects as well as differing namespace aliases.
Extract Style Refactoring
It’s a common situation in XAML to define inline styles for several controls and then relocate them to a style definition. ReSharper makes this operation a breeze with the Extract Style refactoring. The idea is simple: move the cursor to the element to extract styles from, press Ctrl+Shift+R and choose the Extract Style option:
You are presented with the dialog asking you which resource to extract the properties into (you can choose an existing resource or make a new one) as well as what properties you want to extract:
And the end result is predictable – the chosen properties get moved into a <Style>
definition and the element now has a Style
attribute referring to the corresponding StaticResource
.
There are plenty of nuances related to the above refactoring. For WPF, it knows how to extract event subscriptions into an <EventSetter>
. It cleverly filters out things that cannot be extracted. And just like all ReSharper refactorings, it gracefully handles conflict resolution in situations where, for example, you’re extracting attributes that are tied to the code-behind file.
Also, in cases where a style is defined explicitly, additional attributes can be moved to that same style with a context action:
The above works in the same manner as Extract Style but without any dialogs being shown (assuming there are no conflicts).
Extract/Move Resource Refactoring
Another refactoring making its appearance in ReSharper 8 is the Extract Resource refactoring. This refactoring lets you take virtually any property assignment (including those in markup extensions), move it to a resource and reference it. For example, the code below has the string 'abc'
defined three times:
When we invoke the refactoring, we can apply it to just one location or to all three locations that are in scope:
ReSharper then shows a dialog asking you where exactly you want the extracted resource to be placed:
You can probably guess what the end result looks like:
Incidentally, if you were to invoke this refactoring while alrady on a resource, it will function as a Move Resource refactoring. And note that you can move a resource around with the combination of Ctrl+Shift+Alt and the arrow keys:
Inline Resource Refactoring
The exact opposite of resource extraction is the Inline Resource refactoring, which lets you take the definition out of a resource and splice it right into the element that uses it:
Invoking this action checks for possible conflicts and shows a set of options for how you want the resource to be inlined:
Atomic Renaming of Dependency Properties
ReSharper 8 now supports atomic renaming of dependency properties. This means that:
-
Renaming a dependency property performs the correct renaming of its
get/set
property (assuming it follows the standard naming convention) as well as the use of the property name in a string literal. -
This mechanism also works for routed event definitions.
-
If you are following the convention of using static
SetFoo/GetFoo
methods to change properties orAddFooHandler/RemoveFooHandler
for events, atomic renames are also available on/affect these methods too.
Odds and Ends
Here are just a few more things that we’ve added to aid you when working with XAML:
-
Quite often in XAML bindings we bind to something untyped with the understanding that we’ll have something typed at runtime. ReSharper cannot process such an untyped definition, but it now provides a quick-fix to qualify the owner type of the property:
The above effectively lets you pick a concrete type and redefines the binding path toDataContext.(app:MyViewModel.PropertyOfMyViewModel)
. -
In cases where you have unused namespace aliases, ReSharper now provides a quick-fix for one or all such occurences:
-
We also added context actions for quickly removing a markup property or a whole attribute:
And, finally, we all know how annoying it is to have to change XAML tags from open-closed to self-closing, so in ReSharper 8 we provide a Code Cleanup action to do this automatically accross the whole file, project or solution!
Conclusion
Hopefully this War and Peace-sized post is enough to convince you that we are taking XAML support very seriously. As always, if you’re interested in seeing all these features in action right now, we recommend you simply grab the EAP and see them for yourself. Good luck!