Changes to Visual Studio 2015 XAML debugging tools in RC

XAML Debugging Tools in Review

In my last review of the new Visual Studio 2015 XAML debugging tools (xaml-debugging-tools-vs-snoop) I found a lot to like but a few key shortcomings compared to what has been available in Snoop.

Now that the Release Candidate of Visual Studio 2015 has been released the tools are farther along and closer to what their final state will be at RTM. So how are things progressing? Pretty well!

Most of the key features I identified last time are the same but getting more polished overall. Most of the new changes are in the Live Property Explorer.

Property Explorer in VS 2015 RC

(more…)

Read More

Visual Studio 2015 XAML debugging tools from a Snoop perspective

*Update for new RC features: http://codemindinterface.com/2015/05/changes-to-visual-studio-2015-xaml-debugging-tools-in-rc/

Anyone who has done a significant amount of work in WPF is probably familiar with XAML debugging tools like Snoop. A few other tools have come along since with similar functionality that also works across different XAML platforms, but for WPF Snoop still packs a punch. Finally, after almost a decade, Visual Studio is getting the kind of visual tree debugging that’s been an essential part of XAML development (and it will work on all XAML platforms). But given that the tools are brand new (actually still in pre-release, CTP6, as of now) and live inside VS itself rather than a standalone app, how do they stack up? (more…)

Read More

Breaking XAML Stretch with StackPanel

A StackPanel works great as far as stretching in one direction (opposite the orientation): it behaves just like a Star sized Grid with one row or column. The problem happens in the direction of the StackPanel’s Orientation, where it behaves as an infinitely sized container. This results in the StackPanel passing an available width or height of Infinity to each of its children, which for some types of elements can make it difficult to size properly. This can be easy to diagnose for direct children of the StackPanel and is often easy to fix. Unfortunately the problem is inherited by any child contained anywhere under the StackPanel and can become significantly harder to debug.

StackPanel children

In the case of direct children the fix can be straightforward but depends on the desired final layout. Let’s start with a simple example of a Horizontal StackPanel containing a TextBlock. In this case the text is too long to fit in the available space but even though TextWrapping is set to Wrap it stays on a single line and runs off the screen.

<StackPanel Orientation="Horizontal">
	<Button Content="Reset"/>
	<TextBlock TextWrapping="Wrap" FontSize="18">
		This is some long text that should wrap to a new line and not run out of the window.
	</TextBlock>
	<Button Content="Submit"/>
</StackPanel>

Text fails to wrap in StackPanel

(more…)

Read More

Optimizing INotifyPropertyChanged for performance vs convenience

One of the central aspects of implementing the MVVM pattern is the ubiquitous invocations of INotifyPropertyChanged.PropertyChanged in property setters. The simplest version that is commonly seen just passes the property name as a string and builds an EventArgs object in the shared NotifyPropertyChanged method.

public int MyProperty
{
	get { return _myProperty; }
	set
	{
		if (_myProperty == value)
			return;
		_myProperty = value;
		NotifyPropertyChanged("MyProperty");
	}
}

Over time, the verbosity of the basic pattern boilerplate has been reduced in various ways, usually with one of two goals: shorter code or stronger links between the event args and the name of the property itself. One nice technique takes advantage of expressions to create a compile time check on the argument’s match to the a valid property name.

public int MyProperty
{
	get { return _myProperty; }
	set
	{
		if (_myProperty == value)
			return;
		_myProperty = value;
		NotifyPropertyChanged(() => MyProperty);
	}
}

One of the best techniques to emerge so far came about with the release of .NET 4.5 and C# 5 which added the CallerMemberName attribute to automatically resolve the name of the calling property. This provides even easier code and a dead simple implementation in the calling method as well, but does lose out on the ability to make compiler checked calls from outside of the property itself where the property name still must be passed as a string.

public int MyProperty
{
	get { return _myProperty; }
	set
	{
		if (_myProperty == value)
			return;
		_myProperty = value;
		NotifyPropertyChanged();
	}
}

On the other end of the spectrum, pulling all of the responsibility for constructing event args up to the property requires a lot of extra code but can also allow for skipping the allocation of a new PropertyChangedEventArgs object for each call.

static readonly PropertyChangedEventArgs MyPropertyArgs = new PropertyChangedEventArgs("MyProperty");
public int MyProperty
{
	get { return _myProperty; }
	set
	{
		if (_myProperty == value)
			return;
		_myProperty = value;
		NotifyPropertyChanged(MyPropertyArgs);
	}
}

 

It’s great to have all of these options for structuring your code, but how do these all affect performance when lots of data is changing at once? To do some analysis I set up a ViewModel which used each of these variations and ran large timed batches of property changes to get some comparison times. I used each of the four patterns above, with an additional variation on the statically declared PropertyChangedEventArgs which takes advantage of the new nameof operator in C# 6 (VS 2015) to provide compile time checking of the property name.

Explicit String

CallerMemberName

Expression

Static EventArgs

Static EventArgs with nameof

Avg (ms)

10.31

10.63

215.89

9.45

9.65

Median (ms)

10.18

10.35

213.30

9.33

9.43

A few things become clear from this:

  1. The expression method, while providing compile time safety for .NET 4.0 and earlier, is slower to such a degree that it probably shouldn’t be used in any sort of data-intensive UI or in any .NET 4.5+ situation.
  2. The corresponding compiler checked versions of the both of the string based approaches turn out to be a little slower but not enough that it should be noticeable in any but the most performance sensitive scenarios. The added safety of the checks (provided you’re using a new enough language version) should be worth the small cost.
  3. Avoiding repeated allocations of PropertyChangedEventArgs is definitely the fastest method, but based on CPU time probably not a significant enough improvement in most cases to justify the large amount of extra code needed for each property. It is possible that taking memory usage and garbage collection impact into account might provide a more decisive advantage but overall the memory impact of the tiny PropertyChangedEventArgs is likely to be dwarfed in most cases by that of corresponding UIElement objects which are receiving the notifications.

CallerMemberName is probably the best compromise most of the time since it gives up very little in terms of performance but makes for the cleanest code, at least until hopefully some form of automatic notifications on auto-properties can be baked into some future version of C#.

For details of the implementations of each strategy download the test code: Example Implementations

Read More

Digesting the flood of announcements from Visual Studio Connect()

Day 1 of the Visual Studio Connect() event today was packed with announcements, some of which are pretty dramatic changes to the Microsoft development landscape.

The obvious headline announcement which everyone is talking about (and will likely continue to) is the Open Sourcing and Mac/Linux support for the .NET Core Framework. This, along with the NuGet deployment mechanism for app-local copies of the framework, are going to be a huge shift in how .NET apps are developed, deployed, and run on the server. News and commentary is all over the web but Scott Gu’s blog post is a good place to start.

Probably my favorite news of the day was WPF finally emerging from hibernation. The platform is moving forward with fixes to reported issues and general improvements to the platform. Even more exciting, the tooling is getting some long needed attention: visual tree debugging a la Snoop, performance analysis tools, a full refresh of Blend, and a commitment to keep moving the tooling forward for all of the XAML platforms. Read the full roadmap blog post for all the details.

Some of the other under-the-radar announcements came on the Visual Studio side. The integration of MS Research’s Pex project as the new Smart Unit Tests feature should be an interesting addition and is a feature I expect to grow over time into a really powerful code validation tool. Although Roslyn has been out in the wild in CTP form for a while now, the IDE features around it are really starting to come together in the newly released 2015 Preview. Already in this preview a lot of CodeRush/Resharper-like features have been added and the extensibility model is so much better than it has been in the past that I expect community contributions of new code validation and refactoring features to explode over the next few months. My biggest concern at this point is actually around how to manage large sets of these extensions as I don’t think it would be out of the question to end up installing 100+ on top of the built in functionality. Check out details on what’s in the preview and go try it out!

Read More

Getting started with Universal Apps

*Written for Visual Studio 2013 Update 2 RC release

The recently introduced Universal apps for Windows are a significant improvement on the previous level of code sharing available across XAML platforms. For the first time you can share not only PCL compliant .NET code but also a significant amount of XAML, and additional UI related assets like language resources. For MVVM apps this now can mean adding sharing of Views on top of shared Models and ViewModels that can be created with today’s PCLs.

Creating a Universal app starts with creating the new project type, in this case I’ll pick the Blank template.

image

From this template, you will get not one, but three project nodes created for you: the Windows 8.1 Modern app, the Windows Phone 8.1 app, and a completely new type – the Shared project. They’re all placed in a Solution (and also physical) folder to keep them together.

(more…)

Read More