{"id":24820,"date":"2016-03-02T09:24:59","date_gmt":"2016-03-02T17:24:59","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=24820"},"modified":"2020-09-08T09:39:44","modified_gmt":"2020-09-08T16:39:44","slug":"customizing-list-view-cells-xamarin-forms-datatemplateselector","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/customizing-list-view-cells-xamarin-forms-datatemplateselector\/","title":{"rendered":"Customizing ListView Cells with Xamarin.Forms&#8217; DataTemplateSelector"},"content":{"rendered":"<pre><code>            Many mobile apps have to display a list of data to users, so it's no surprise that the list view is a fundamental control seen in almost every app. Xamarin.Forms' &lt;code&gt;ListView&lt;\/code&gt; allows you to display a list of data using cells and a &lt;code&gt;DataTemplate&lt;\/code&gt; to bind between a data source and the cell. Using this approach, you could easily customize an existing cell or create a completely new look and feel by extending the &lt;code&gt;ViewCell&lt;\/code&gt;. However, this type of customization has one key limitation: the inability to render different types of cells in the same &lt;code&gt;ListView&lt;\/code&gt; at runtime.\n<\/code><\/pre>\n<p>Xamarin.Forms 2.1 introduces <code>DataTemplateSelector<\/code>, which is a powerful mechanism to customize the presentation of a cell at runtime. While <code>DataTemplate<\/code> is used to specify the visualization of your data objects, a <code>DataTemplateSelector<\/code> is used to choose a <code>DataTemplate<\/code> at runtime based on the value of a data-bound property.<\/p>\n<p>In this blog post, we&#8217;ll be using the <code>DataTemplateSelector<\/code> to <a href=\"https:\/\/github.com\/nishanil\/Xamarin.Forms-Samples\/tree\/master\/DataTemplateSelector\">create a simple chat user interface<\/a> (seen below), which will customize the look of the cell with different colors and alignment based on an incoming and outgoing message.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Hero-DataTemplateSelector-1.png\" alt=\"\" width=\"500\" height=\"457\" class=\"aligncenter size-full wp-image-37438\" \/><\/p>\n<h2>Getting Started with Xamarin.Forms DataTemplateSelector<\/h2>\n<p>Selecting a <code>DataTemplate<\/code> at runtime can be implemented in just two easy steps:<\/p>\n<ol>\n<li>Create a class that inherits from <code>DataTemplateSelector<\/code> and override the <code>OnSelectTemplate<\/code> method to select a particular <code>DataTemplate<\/code>.<\/li>\n<li>Wire the <code>DataTemplateSelector<\/code> to the <code>ListView<\/code> by setting the <code>ItemTemplate<\/code> property.<\/li>\n<\/ol>\n<h3>Create a DataTemplateSelector<\/h3>\n<p>To customize cells, create a custom class that inherits from <code>DataTemplateSelector<\/code> and override the <code>OnSelectTemplate<\/code> method. The parameter item provides you the bound data of the cell, which in turn can be used to write logic to generate a custom template. In this example, the binding context is a <code>MessageViewModel<\/code>, which is then used to determine which type of data template should be displayed. We have defined two DataTemplates&mdash;<code>incomingDataTemplate<\/code> and <code>outgoingDataTemplate<\/code>. The <code>OnSelectTemplate<\/code> method returns appropriate template based on if the message is incoming or outgoing. To ensure that we avoid potential memory leaks, it&#8217;s always important to keep a reference to each data template in memory.<\/p>\n<pre class=\"lang:c# decode:true\">class MyDataTemplateSelector : Xamarin.Forms.DataTemplateSelector\n{\n    public MyDataTemplateSelector()\n    {\n        \/\/ Retain instances!\n        this.incomingDataTemplate = new DataTemplate(typeof(IncomingViewCell));\n        this.outgoingDataTemplate = new DataTemplate(typeof(OutgoingViewCell));\n    }\n\n    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)\n    {\n        var messageVm = item as MessageViewModel;\n        if (messageVm == null)\n            return null;\n        return messageVm.IsIncoming ? this.incomingDataTemplate : this.outgoingDataTemplate;\n    }\n\n    private readonly DataTemplate incomingDataTemplate;\n    private readonly DataTemplate outgoingDataTemplate;\n}\n<\/pre>\n<h3>Applying the DataTemplateSelector in XAML<\/h3>\n<p>There are multiple ways you can reference the <code>DataTemplateSelector<\/code> in XAML. Either you can create an instance of the selector in your ViewModel and bind them to the <code>ListView<\/code>&#8216;s <code>ItemTemplate<\/code> property or create a static resource within <code>ResourceDictionary<\/code> and directly reference them in ListView, as seen below:<\/p>\n<pre class=\"lang:c# decode:true\">    \n  \n    \n      \n    \n  \n\n  \n    \n<\/pre>\n<p>When using <code>DataTemplateSelectors<\/code>, it&#8217;s important to keep in mind the following limitations:<\/p>\n<ul>\n<li>No more than 20 templates per <code>ListView<\/code> on Android.<\/li>\n<li>The <code>DataTemplateSelector<\/code> subclass MUST return the same template for the same data if queried multiple times.<\/li>\n<li>The <code>DataTemplateSelector<\/code> must not return another <code>DataTemplateSelector.<\/code><\/li>\n<li>The <code>DataTemplateSelector<\/code> must not return new instances of a DataTemplate on each call, instead the same instance must be returned. Failure to do so will effectively disable virtualization and lead to a memory leak.<\/li>\n<\/ul>\n<h2>Wrapping Up<\/h2>\n<p><code>DataTemplateSelector<\/code>s are a useful approach for customizing a <code>ListView<\/code> at the runtime based on a custom defined logic. In addition, since the UI code is logically separated from the code that takes care of template selections, it results in massively increased code maintainability and testability. <a href=\"https:\/\/github.com\/nishanil\/Xamarin.Forms-Samples\/tree\/master\/DataTemplateSelector\">Download the chat user interface sample<\/a> shown today to get started with Xamarin.Forms 2.1&#8217;s <code>DataTemplateSelector<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many mobile apps have to display a list of data to users, so it&#8217;s no surprise that the list view is a fundamental control seen in almost every app. Xamarin.Forms&#8217; &lt;code&gt;ListView&lt;\/code&gt; allows you to display a list of data using cells and a &lt;code&gt;DataTemplate&lt;\/code&gt; to bind between a data source and the cell. Using this [&hellip;]<\/p>\n","protected":false},"author":593,"featured_media":24824,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[16],"class_list":["post-24820","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Many mobile apps have to display a list of data to users, so it&#8217;s no surprise that the list view is a fundamental control seen in almost every app. Xamarin.Forms&#8217; &lt;code&gt;ListView&lt;\/code&gt; allows you to display a list of data using cells and a &lt;code&gt;DataTemplate&lt;\/code&gt; to bind between a data source and the cell. Using this [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/24820","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/593"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=24820"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/24820\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=24820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=24820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=24820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}