XAML - James Montemagno https://staging.montemagno.com/tag/xaml/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png XAML - James Montemagno https://staging.montemagno.com/tag/xaml/ Hugo -- gohugo.io Tue, 13 Oct 2026 20:48:55 GMT 60 Code Generation from XAML in Visual Studio is Mind-blowing Awesome https://staging.montemagno.com/code-generation-from-xaml-in-visual-studio/ 605f72ee20df30003b2b3b83 Sat, 27 Mar 2021 18:57:22 GMT

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!

]]>
Xamarin.Forms Design Time Data Tips & Best Practices https://staging.montemagno.com/xamarin-forms-design-time-data-tips-best-practices/ 5d9f5e420980fc00385d9b6a Thu, 10 Oct 2019 21:15:00 GMT

One of my favorite features of building applications with XAML is the ability to use design time data to preview it inside the IDE. Recently in Xamarin.Forms 4.0 the team introduced an official pattern to specify design time properties, controls, or just about anything else. It is a really neat feature that I have been using on my live streams and in my apps. There is some really great docs that you should read through, but I will repeat the core info here.

DesignTime

Why Design Time Data?

Xamarin.Forms XAML Hot Reload is the future ( available today in VS 16.3 and VSM 8.3) for rapid iteration and productivity with XAML, I still sometimes find myself working on new screens or wanting to get a mockup of my UI without having to run my app. Also, sometimes you don't have your ViewModel setup yet and you just want to start building a screen. That is where design time data comes in, allowing you to preview your data without having to run your app. So, let's get started.

Getting Started

The Xamarin.Forms leveraged the basic building blocks of design time data from WPF/UWP and added a few name spaces that you can import into your XAML to start using it.

xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"

If you create a new project or page this will already be included and may even have some design time data already in there. These three lines of code setup the ability to start using design time data with the magical d character. You can of course change this, but d: is a nice and simple. That's it, you are ready to go!

Simple Properties

The previewer will automatically pick up any property that you set, however if you are using data binding then it will not be able to display anything.

<Label Margin="10"
       Text="{Binding MonkeyCount, StringFormat='{0} Monkeys'}"/>

DesignTime1

To get design time data showing up we can simply add d: to a new Text property and assign the value.

<Label Margin="10"
       Text="{Binding MonkeyCount, StringFormat='{0} Monkeys'}"
       d:Text="3 Monkeys"/>

DesignTime2

What is really great is that you can actually set ANY property! This is very nifty when you are trying to figure out spacing and sizing. I love to set the BackgroundColor all the time, but now, I can use design time data to see it only in the previewer.

<Label Margin="10"
       Text="{Binding MonkeyCount, StringFormat='{0} Monkeys'}"
       d:Text="3 Monkeys"
       d:BackgroundColor="Orange"/>

DesignTime3

One of my favorite things to do is to see my ActivityIndicator in the previewer by setting d:IsRunning="True":

<ActivityIndicator
    Grid.RowSpan="2"
    IsVisible="{Binding IsBusy}"
    IsRunning="{Binding IsBusy}"
    d:IsRunning="True"
    HorizontalOptions="Center"
    VerticalOptions="Center"/>

Activity

Lists of Data

One really cool thing about using design time data is that you can also specify an Array of data. This means that you can easily specify a design time ItemsSource on your ListView, CollectionView, CarouselView, etc. This is really great when we want to work on our cells, but don't have the data yet.

<d:ListView.ItemsSource>
    <x:Array Type="{x:Type x:String}">
        <x:String>Item One</x:String>
        <x:String>Item Two</x:String>
        <x:String>Item Three</x:String>
    </x:Array>
</d:ListView.ItemsSource>

Then you can use d: on any property on the cell, or you can use `{Binding .} to bind to the string that you have specified:

<ListView.ItemTemplate>
    <DataTemplate x:DataType="models:Monkey">
        <ImageCell Text="{Binding .}"
                   Detail="{Binding Location}"
                   d:Detail="Location"
                   ImageSource="{Binding Image}"
                   d:ImageSource="icon.png"/>
    </DataTemplate>
</ListView.ItemTemplate>

DesignTIme4

Lists of Model Data

Lucky for us, we can also use our real data model, which means our bindings will actually work! You just need to make sure that your properties you want to use have a public get and set.

<d:ListView.ItemsSource>
    <x:Array Type="{x:Type models:Monkey}">
        <models:Monkey Name="Baboon" Location="Africa and Asia"/>
        <models:Monkey Name="Capuchin Monkey" Location="Central and South America"/>
        <models:Monkey Name="Blue Monkey" Location="Central and East Africa"/>
    </x:Array>
</d:ListView.ItemsSource>
<ListView.ItemTemplate>
    <DataTemplate x:DataType="models:Monkey">
        <ImageCell Text="{Binding Name}"
                   Detail="{Binding Location}"
                   ImageSource="{Binding Image}"
                   d:ImageSource="icon.png"/>
    </DataTemplate>
</ListView.ItemTemplate>

DesignTIme5

Notice that I am still using d:ImageSource because the previewer wont go and download images from the internet. This icon.png is just in my drawable/resource folder and it will be displayed.

Important: You need to re-compile your libraries/app when you make changes to a model or ViewModel so the previewer can re-load it.

ViewModels, IntelliSense, & XAML Hot Reload

Alright, now for what you have been waiting for... ViewModels! A long time ago, I wrote a blog on how to use design time data ViewModels with the previewer. Many developers may be binding their ViewModel directly in their XAML. If you are using XAML Hot Reload then you may have noticed that everytime you reload that your ViewModel gets re-created! My recommendation would be to set your BindingContext in your page constructor:

public MonkeysPage()
{
    InitializeComponent();
    BindingContext = new MonkeysViewModel();
}

Now, the issue here is that you will no longer get IntelliSense in your XAML because the XAML doesn't know about your BindingContext! Don't worry, design time data to the rescue!

<d:ContentPage.BindingContext>
    <viewmodels:MonkeysViewModel/>
</d:ContentPage.BindingContext>

Now your IntelliSense will work again!

IntelliSense

Running ViewModel Logic

Now, you may be saying.. James, but I already have mock ViewModels that are ready to be consumed in my XAML & the previewer. Well, don't worry because while the previewer no longer runs your page's code behind, it will still execute the constructor of your ViewModel! This means you could set your d:ContentPage.BindingContext to the mock ViewModel, or if you need to pass parameters to the constructor to setup mock data, you can do that to.

So, let's say you have something like this for your ViewModel:

public MonkeysViewModel(bool designData)
{
    if (designData)
    {
        Monkeys = MonkeyHelper.Monkeys;
        MonkeysGrouped = MonkeyHelper.MonkeysGrouped;
    }
    else
    {
        //Setup web requests and such
    }
}

We can setup the design time ViewModel in XAML and then remove ALL of the d: bindings that we were using:

<d:ContentPage.BindingContext>
    <viewmodels:MonkeysViewModel IsBusy="True">
        <x:Arguments>
            <x:Boolean>true</x:Boolean>
        </x:Arguments>
    </viewmodels:MonkeysViewModel>
</d:ContentPage.BindingContext>

Final

Future of Design Time Data

Design time data today is pretty cool and works well with the updates to the previewer that the team made to make it more stable. My hope for design time data is that the team opens up the API and actually allows you to use design time data at runtime! That is right! At runtime! I think that this would be super cool and I even opened a GitHub issue that you should go +1 on.

Get the code

As always, you can grab the code on GitHub for the monkeys app and give it a go.

This post is part of the Xamarin October Best Practice Challenge. Checkout the GitHub page for more great posts!

]]>
Xamarin.Forms: How to Clip Images with Rounded Corners https://staging.montemagno.com/xamarin-forms-how-to-clip-images-with-rounded-corners/ 5d3a79f30ffbc60038e301b1 Fri, 26 Jul 2019 17:00:00 GMT

I love watching trends in mobile design. Currently gradients are all the rage, but two trends that have been around for a while are rounded corners and circular images. A long time ago I created the Circle Image plugin for Xamarin.Forms that many developers know and love, but did you know that you can just use built in controls to get a circle or rounded corners? All you have to do is use a frame and set a few special properties!

Let's start slow and just put a beautiful Red-shanked Douc Langur on our Page:

<StackLayout Padding="40">
    <Image Source="monkey.jpg"
       HorizontalOptions="Center"
       VerticalOptions="Center" />
</StackLayout>

Monkey

Now let's wrap this cutie in a Frame ensuring we set the Padding to 0, as it defaults to a large number, and the CornerRadius to what we would like:

<StackLayout Padding="40">
    <Frame CornerRadius="20"
           Padding="0">
        <Image Source="monkey.jpg"
           HorizontalOptions="Center"
           VerticalOptions="Center" />
    </Frame>
</StackLayout>

Monkey2

Wait a second... where are our rounded corners? Well this is because we need to set the IsClippedToBounds property to ensure that the image gets clipped correctly:

<StackLayout Padding="40">
    <Frame CornerRadius="20"
           Padding="0"
           IsClippedToBounds="True">
        <Image Source="monkey.jpg"
           HorizontalOptions="Center"
           VerticalOptions="Center" />
    </Frame>
</StackLayout>

Monkey3

Circular Images with Frame

One of my favorite features of Frame is that if you set the Width and Height you can create a circle image by setting the CornerRadius to half of the Width/Height:

<StackLayout Padding="40">
    <Frame CornerRadius="100"
           HeightRequest="200"
           WidthRequest="200"
           HorizontalOptions="Center"
           Padding="0"
           IsClippedToBounds="True">
        <Image Source="monkey.jpg"
           HorizontalOptions="Center"
           VerticalOptions="Center" />
    </Frame>
</StackLayout>

Monkey4

Here it is using XAML Hot Reload 🔥🔁

Circles

This approach is also works if you are using the incredible PancakeView control that also supports gradients!

pancake

Xamarin.Forms 5

If you have upgraded to Xamarin.Forms 5 then you can optionally use the brand new Shapes API. Everything view can be "Clipped". It is one of my new favorite features, and I use it all the time because it doesn't introduce a new view to the heirarcy.

<StackLayout Padding="40">
    <Image Source="monkey.jpg"
       WidthRequest="100"
       HeightRequest="100"
       HorizontalOptions="Center"
       VerticalOptions="Center">
        <Image.Clip>
            <EllipseGeometry
                Center="50,50"
                RadiusX="50"
                RadiusY="50"/>
        </Image.Clip>
    </Image>
</StackLayout>

This will give you the same exact effect :)

]]>
Why Xamarin.Forms Embedding Matters https://staging.montemagno.com/why-xamarinforms-embedding-matters/ 598df8f2c121b60019bf2fc4 Tue, 20 Jun 2017 18:20:35 GMT Last week I wrote about Xamarin.Forms Embedding, a great new feature of Xamarin.Forms, that enables developers to convert a Xamarin.Forms ContentPage into an iOS UIViewController, Android Fragment, and a UWP Page. I walked through the current setup and a real world example of adding Xamarin.Forms details pages to my Xamarin Native application which previously only had native Storyboards and Android XML pages. When I originally got this setup and working I was blown away by this feature and it is something that I have wanted for so long out of Xamarin.Forms, but some people seemed to be confused by the feature and why it matters or what it actually does.

Forms Embedding

Sharing Code with Xamarin

Traditionally with Xamarin applications (before Xamarin.Forms) we would build out our native user interfaces with Storyboards, XML, and XAML for each platform “head” that we wanted to develop for. The key though is that with Xamarin you have access to 100% of APIs all from C# and all of your code behind for those native views are all in C# with awesome C# features. Everything compiles down into lovely native apps that look and feel native… you guessed it because they are native. This is unlike other cross-platform frameworks that are just abstractions or some sort of webview… Xamarin apps are 100% native.

What comes next is the magic that with Xamarin you have a full .NET runtime that runs native on each platform enabling anyone to share a vast majority of the apps business logic between all of their apps and even their existing desktop and websites. This logic usually is all of the models, view models, and service logic that is just pure .NET code that is now cross-platform to nearly any platform. On average I share about 70% of code across all of my applications that I build with Xamarin and I am using super productive tools like Visual Studio and of course using the best programming language, C#.<

What about the User Interface?

The one thing that isn’t shared though is the user interface. This was a hard problem because you don’t want to lose the native part of Xamarin which makes it so unique. Other cross-platform UI frameworks just fake it and lack great performance and don’t really display the native UIs and are very messy. This is why Xamarin.Forms was designed differently. Abstract what is common into a XAML schema with a full MVVM & data binding framework built in. If you don’t know about MVVM & Databinding and why it matters listen to our latest Merge Conflict:

The difference with Xamarin.Forms is that everything that actually gets displayed are native controls for each platform. It is just this thin layer on top with a bunch of great features including Messaging Services, Dependency Services, and full navigation.

So I Should Just Use Xamarin.Forms?

Xamarin.Forms is spectacular and I have been quoted many times that 80% of all applications could be built with Xamarin.Forms especially seeing a bulk of all applications are built for the enterprise scenarios. This is where Xamarin.Forms shines and was NEVER sold as the silver bullet that everyone thought it was. If you have heard me present I have always said that my first love will always be Xamarin Native and when I am building an app that needs sub-2 second startup, access to tons of native libraries and controls such as material design, and want full control then I would always recommend Xamarin Native as you are still sharing 60-70%+ of code!

Until now developers could only pick one or the other. You had to pick Xamarin Native or Xamarin.Forms and trying to blend the worlds wasn’t the easiest to do and transitioning from a POC (proof of concept) and throw away the Xamarin.Forms user interface seemed like a waste. Or maybe you already had a Xamarin Native app and just want to share more code without having to re-write your whole app. This is where Xamarin.Forms Embedding comes in.

Xamarin.Forms Embedding Is AWESOME

Xamarin.Forms Embedding enables Xamarin Native developers to leverage Xamarin.Forms including a bunch of its great features (including data binding) to create shared user interface pages for their applications in Xamarin.Forms and embed them in their Xamarin Native apps. That is correct, you can now start replacing all of those simple screens (about, settings, details) that you had to write three times with a SINGLE XAML/Xamarin.Forms based page that is shared across all of your applications.

This is truly game changing when it comes to choosing Xamarin and Xamarin.Forms as your mobile app development platform. You can benefit from all of your performance and design of a Xamarin Native application without any overhead at all and embed those shared pages directly into your apps. You can dabble in Xamarin.Forms without the commitment. Need to develop a feature quickly? No problem because embedding will save you TONS of time. The code is so simplistic that it can now take that 60-70% up to 80-90%+ when developing a Xamarin Native app, which is simply awesome.

Embedding Everything Everywhere

Forms Embedding

To me this is really only the first step to where Embedding will go. At Build 2017 I got to help announce the Embeddinator-4000 project which enables developers to compile and embed a .NET or Xamarin.IOS/Android/Mac library into a native language library (Objective-C/Swift/Java/C++). This means that non-Xamarin developers can now create that shared code layer for their applications without having to take the leap and re-writing their full application as this usually is not an option. Now, let’s look into the future when Embeddinator is complete and Xamarin.Forms Embedding has hit stable where a mobile app developer writing an Objective-C iOS and Java Android app could adopt Xamarin into their native application and share not only business logic, but also create shareable NATIVE user interface with Xamarin.Forms Embedding. This is the story I want to tell, this is unbelievably amazing, and I can’t wait for this embedding future!

These reasons are why Xamarin.Forms embedding matters, why you should care, and why you should give it a try today. If you still don’t believe me after reading this then watch it in action:

]]>
Important OnPlatform Changes in Xamarin.Forms https://staging.montemagno.com/important-onplatform-changes-xamarin-forms/ 598df8f2c121b60019bf2fca Mon, 17 Apr 2017 18:15:05 GMT Last week I blogged about the important changes to Device.OS in the latest version of Xamarin.Forms. Well, I am back with some other changes from that same exact Pull Request that have to do with OnPlatform in code and XAML that use the new Device.RuntimePlatform.

So, what is OnPlatform? It allows you to set properties on elements or run specific code based on specific platforms. This is really nifty for tiny tweaks to UI and can be done completely in the XAML, which is awesome. To make way for furture enhancements there have been small tweaks to the XAML and code behind implementations.

First, XAML. Instead of having to support all the crazy inline options for hard coded platforms we can simply use string versions of each platform. Here is a before and after:

Easy peasy to update actually and allows for custom platforms in the future.

How about the favorite Device.OnPlatform method? Well I never really liked this method to be honest with you and apparently it wasn’t very flexible long term. So instead of passing in a bunch of Actions into a crazy method the new recommendation is to simply do a switch case over Device.RuntimePlatform! Check it out:

There you have it, quick and simple changes available now in 2.3.4 of Xamarin.Forms.

]]>
Xamarin.Forms XAML Previewer Design Time Data https://staging.montemagno.com/xamarinforms-xaml-previewer-design-time-data/ 598df8f2c121b60019bf2ff1 Sun, 01 May 2016 21:08:39 GMT UPDATE

Checkout my newly updated blog on Design Time Data best practices that are updated for the most recent changes in Xamarin.Forms.

Original Post

The most annticipated announcement of Xamarin Evolve 2016 had to be the Xamarin.Forms xAML Previewer. Enabling you to see a live preview of your Xamarin.Forms XAML without having to run it on a simulator or device. Simply write some XAML and there it is running on an iOS or Android phone or simulator design surface.

Writing XAML and seeing it is fine, but what if you want to see sample data right inside of your preview? I mean doesn’t each View have a ViewModel associated with it? If so, then would’t we like to use it during design time?

Return of the ViewModelLocator!

During the keynote Nina showed off a list of Coffees where the ItemSource was bound to some design time data. I first thought about taking this approach and create a static List for my Monkeys app, but then I thought there has to be a better way. Essentially, Laurent taught us years ago how to create a static ViewModelLocator class that can be used at design time. So here is the setup, simply create a new class called ViewModellLocator.cs and create a static version of each ViewModel you wish to use (I personally put it in my App.cs):

public static class ViewModelLocator
{
    static MonkeysViewModel monkeysVM;

    public static MonkeysViewModel MonkeysViewModel =>
       monkeysVM ?? (monkeysVM = new MonkeysViewModel());
}

Note: you could pass in some additional arguments to tell your view model you are in design mode.

Design Time

Next up is to head over to your XAML file and create a new xmlns:design on your Page that refers to the assembly that you are using.

xmlns:design="clr-namespace:Monkeys;assembly=Monkeys"

Then you can set BindingContext of the page to your design time static view model:

BindingContext="{x:Static design:ViewModelLocator.MonkeysViewModel}"

See it live!

Now the rest of your Bindings will all just work, which is pretty much fantastic.

Here is a short video walking through the process:

Don’t forget that it even renders your custom renders. Awesome! Be sure to read the Evolve blog post announcing all these awesome features.

]]>
Enhancing Xamarin.Forms ListView with Grouping Headers https://staging.montemagno.com/enhancing-xamarin-forms-listview-with-grouping/ 598df8f2c121b60019bf3028 Wed, 13 Aug 2014 17:27:00 GMT Sometimes a plain ListView just isn’t good enough. You can easily spice it up with images or custom cells, but what about organizing the data. With C# and LINQ it is easy to sort your list, but how about giving it some visuals? How about some headers? With Xamarin.Forms it is extremely simple to add in headers and to create a custom view as well.

I am working out of my Xamarin.Forms-Monkeys project that I have blogged about before, which consists of a nice list of Monkeys with Images. You can browse this code on my GitHub.

Bindable Group Structure

There are a few examples of using headers with Xamarin.Forms, but I wanted to create an ultimate “Group” that would allow me to sort, organize any data, and that is when I came up with Grouping:

Grouping seems simple, but is very extensible, especially if using data binding. Notice that a Grouping is really just an ObservableCollection of type T. However, each Grouping also has a Key. Now this key is of type K, which means it could be anything including a complex data structure. This means you could in theory bind your header to a data structure of K and then bind multiple controls to multiple properties, which is very cool. For this example though we will just make K a string for sorting.

Sorting Our Monkeys

Before we get to our Monkeys we will create a new new public ObservableCollection<Grouping<string,Monkey> > MonkeysGrouped{get;set;} in our ViewModel. The reason for this is that we actually have multiple lists, which is a list of a list of grouped monkeys. Then we will add a new property to our monkey that we can use for sorting, which will be a name sort property:

And now we can sort our list of Monkeys in our view model, which we will set as the ItemsSource on our list view:

Enabling Headers

Enabling headers is very simple. There are a few properties to set on the ListView itself to get things going. First is to enable grouping, and then to set the property that the headers will bind to:

list.ItemsSource = viewModel.MonkeysGrouped;
list.IsGroupingEnabled = true;
list.GroupDisplayBinding = new Binding("Key"); //this is our key property on grouping.

Jump List

Of course, we could stop there, but what fun would that be, as we can add a jump list with just a single line of code:

list.GroupShortNameBinding = new Binding("Key");

This results in a nice jump list:

Custom Headers

Let’s take it one step further and implement our own custom header cell with a nice background color. Right now our Key, K, is only a string, but we could pass in a full data structure if we wanted to make the custom view more complex and bind to multiple pieces of information.

My HeaderCell is very simple and just contains a Label, which binds to Key and I am placing it inside of a StackLayout with a bit of custom padding and a background color. It should be noted that I am setting a fixed Height of 25 here as the Xamarin.Forms ListView needs to know what to render.

The last thing to do is to update the the ListView with this new template:

if(Device.OS != TargetPlatform.WinPhone)
  list.GroupHeaderTemplate = new DataTemplate(typeof(HeaderCell));

list.HasUnevenRows = true; //you might want to enable if using custom cells.

We don’t set it on Windows Phone because the default styling is standard on Windows Phone with accent colors. However, you can customize it here as well. Here is our outcome on all three platforms:

XAML?

As Charles Petzold would say… Show me the XAML! Of course it is just as easy, as all we need to do is bring over our updated ViewModel and Grouping and create the rest all in XAML:

Conclusion

It is extremely easy to not only customize your cells in your ListView, but also add rich functionality like list sorting with group headers with just a few lines of shared C# code with Xamarin.Forms!

]]>