James Montemagno
James Montemagno

Live, Love, Bike, and Code.

Live, Love, Bike, and Code

Share


Tags


James Montemagno

Code Generation from XAML in Visual Studio is Mind-blowing Awesome

The more and IDE or code editor can do for you the better I say. Visual Studio has been crushing it with new refactorings, IntelliSense, and IntelliCode, one of my favorite features ever. One thing that I have always been hoping for as a XAML developer is deeper connectivity between the XAML and the View-Model. We have seen increased IntelliSense in this area, but with the release of Visual Studio 2019 v16.9 comes code generation from XAML! That is right, you can now have Visual Studio automatically create your properties, commands, and more!

I will walk through this awesome feature for Xamarin.Forms, WPF, and UWP, but if you just want to see it in action, I made an entire video:

Enabling Code Generation

The first thing to do is to create your ViewModel and implement INotifyPropertyChanged (or inherit from something that does). Then just create a control with a Binding associated with it. For example:

<StackLayout>
    <Label Text="{Binding Text}"/>
</StackLayout>

Once you do this, Visual Studio will put little dots under the Text binding and a lightbulb will show up (if you don't see this simply re-compile). The lightbulb will look to assign your x:DataType in Xamarin.Forms or d:DataContext in WPF/UWP.

Lightbulb in Visual studio to set x:DataType

When I selected this option, it auto added the following code:

xmlns:app1="clr-namespace:App1"
x:DataType="app1:MyViewModel"

What is x:DataType you may be asking? Well, it is a compiled binding, which makes your bindings and apps faster! This is an awesome feature of Xamarin.Forms that you should totally use!

With this code in place, you will now see the dots remain and a new lightbulb show up to create a property called Text for you!

Lightbulb and code preview to generate text

Here, it is recommending adding the property and creating a SetProperty method to invoke PropertyChanged, which is AWESOME!!!! Now, at this point you probably want to refactor the code a little bit and create  BaseViewModel that you put this method in and then in future ViewModels it will not attempt to create the code and just add the property. If you are using Mvvm Helpers, you can use this code as your base:

public class ViewModelBase : BaseViewModel
{
	public bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null) =>
		SetProperty<T>(ref field, newValue, propertyName, null, null);
}

Now, if you add another control with another binding, you will see nice tight code will be generated for you:

Another property being added with only a get/set

Is your mind blown yet?!?!? Mine is! However, it gets even better!

Generating Commands!

Now, let's say we are going to add a Command to a Button we would naturally want that code to be generated as well, correct? Well, you are in luck because it will!

Command and method being created!

This code is really neat because it not only created the command and the method, but it also brought in the correct namespace to use the Xamarin.Forms Command!

Command Generation on UWP/WPF

If you are over on UWP or WPF you will not see this code generation because the core framework does not have an implementation of ICommand. However, if you are using a framework or library such as Mvvm Helpers then it will be smart enough to figure it out and recommend code for you!

Code for a command being generated with Mvvm Helpers

MIND BLOWN!!!! ARE YOU NOT IMPRESSED!?!?!? Amazing!

Cleaner Code with C# 8 & 9!

One of the things you may have noticed is that the code for Xamarin.Forms and WPF/UWP are different in the screenshots. That is because my WPF sample app is using .NET 5, which uses C# 9 by default. The Xamrin.Forms app is using .NET Standard 2.0, which defaults to C# 7. However, you can easily adjust what version of C# is used in your project by adding the LangVersion into your csproj.

<LangVersion>8.0</LangVersion>

Take a look at my previous blog about upgraded a project to C# 9 in a minute.

Once you upgrade to 8.0 or higher the old code:

private ICommand clickCommand;

public ICommand ClickCommand
{
	get
	{
		if (clickCommand == null)
		{
			clickCommand = new Command(Click);
		}

		return clickCommand;
	}
}

private void Click()
{
}

will be upgraded to this lovely clean tight code:

private ICommand clickCommand;
public ICommand ClickCommand => clickCommand ??= new Command(Click);

private void Click()
{
}

Code Generation for Models

So far we have had Visual Studio generate code in our ViewModel classes on our page, but what about our models that are bound to an ItemsSource in a ListView or CollectionView Well no worries, all you need to do is set your x:DataType on your DataTemplate:

<ListView ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="app1:Item">
            <ViewCell>
                <Label Text="{Binding Text}"/>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Then you will see lightbulbs on any control inside of the DataTemplate!!

Code being generated inside of the data model

Again, this is pretty mind blowing and amazing! I was able to create all of my ViewModels and Models all without leaving the XAML!

Just the start!

This is all from me just playing around with Visual Studio 2019 v16.9 for a few minutes exploring this awesome new feature. There is for sure much more to come as Marco from the XAML Tooling team tweeted about the new feature and discussed with commentors about extending the templates for code that is being generated. Also, as of right now this is just a feature on Visual Studio on Windows, but since Visual Studio for Mac uses pretty much the same engine, we can imagine it will make its way to VSM soon.

This is just one of the many features that was included in Visual Studio 2019 v16.9 so check the release notes and upgrade today!

Copyright © James Montemagno 2021 All rights reserved. Privacy Policy

View Comments