{"id":38496,"date":"2019-01-11T13:06:39","date_gmt":"2019-01-11T18:06:39","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=38496"},"modified":"2019-03-25T13:26:10","modified_gmt":"2019-03-25T21:26:10","slug":"xamarin-forms-3-5-a-little-bindable-love","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/xamarin-forms-3-5-a-little-bindable-love\/","title":{"rendered":"Xamarin.Forms 3.5: A Little Bindable Love"},"content":{"rendered":"<p>\t\t\t\t<em>This is a guest post contributed by <a href=\"https:\/\/twitter.com\/nitescua\">Andrei Nitescu<\/a>, a mobile developer since 2013 and frequent contributor to Xamarin.Forms. He shares about his experiences with other developers on his <a href=\"http:\/\/enginecore.blogspot.com\">blog<\/a>, and delivering talks whenever he has the chance.<\/em><\/p>\n<h2>Xamarin.Forms 3.5<\/h2>\n<p><em>Xamarin.Forms 3.5-pre2 is now available in pre-release on NuGet and via your Visual Studio NuGet package manager. For a complete list of improvements including Andrei&#8217;s BindableLayout contribution, review the <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/release-notes\/3.5\/3.5.0-pre2\">full release notes<\/a>.<\/em><\/p>\n<p>I\u2019d like to share with you some information about one of my contributions to Xamarin.Forms, the <strong>bindable layout<\/strong>. As a developer, I love the potential of the layout views to create visually rich views that delight our app users. Xamarin.Forms, the cross-platform mobile application framework, it&#8217;s more straightforward to create such custom views that work across all mobile platforms. Xamarin.Forms allows us to write the layout logic to set the size and position of the views only once.<\/p>\n<p>While the \u201cbinding layout\u201d name might suggest that it&#8217;s an addition to the base <em>Layout<\/em> view class, it actually works as an adaptor. It takes a source of data items and calls the <em>Layout&lt;T&gt;<\/em> view to create and update its child views based on the changes in the data item source.<\/p>\n<h2>Layouts, a Quick Refresh<\/h2>\n<p><em>(Skip this section and the next one if you already know how layouts and data-binding to layouts work. There is no new information on that.)<\/em><\/p>\n<p>Xamarin.Forms has a special View called Layout. The <em>Layout<\/em> class is a container for other Views and has a specific mission: to <strong>position<\/strong> and <strong>size<\/strong> its child Views. Here\u2019s the class diagram with all the available layouts in the framework today:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/class-diagram.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-38497\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/class-diagram.png\" alt=\"\" width=\"935\" height=\"476\" \/><\/a><\/p>\n<p>The <em>Layout&lt;T&gt;<\/em> class is a specialized Layout which exposes a <em>Children<\/em> View collection. Therefore, we can add, remove, or replace child Views to fit our design requirements:<\/p>\n<pre class=\"lang:c# decode:true\">StackLayout stackLayout =\u2026;\r\n\r\nstackLayout.Children.Add(new Label() { Text = \u2026 });\r\n<\/pre>\n<p><em>Layout&lt;T&gt;<\/em> is the base class for most common layouts some of which you\u2019ve\u00a0<span style=\"float: none;background-color: #ffffff;color: #333333;cursor: text;font-family: Georgia,'Times New Roman','Bitstream Charter',Times,serif;font-size: 16px;font-style: normal;font-variant: normal;font-weight: 400;letter-spacing: normal;text-align: left;text-decoration: none;text-indent: 0px\">already <\/span> been using, like the <em>StackLayout<\/em> or <em>Grid<\/em> for example. The <em>Layout&lt;T&gt;<\/em> makes it possible to create your own layout to size and position child views any way you want; it\u2019s really up to your imagination. There\u2019s excellent documentation and samples on how to build your own custom layouts. Check out <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/user-interface\/layouts\/custom\">Creating a Custom Layout<\/a>.<\/p>\n<h2>Layout + Data Binding<\/h2>\n<p>When creating the item views for a Layout based on a source of data items, you may have code that looks similar to this:<\/p>\n<pre class=\"lang:c# decode:true \">void UpdateItems (StackLayout layout, IEnumerable newDataItems)\r\n{\r\n    layout.Children.Clear ();\r\n    foreach (object dataItem in newDataItems) {\r\n        View itemView = CreateItemView(dataItem);\r\n        layout.Children.Add (itemView);\r\n    }\r\n}<\/pre>\n<p>However, wiring up a collection of data items to a layout view needs to take into account and handle several aspects. For example, we need to check if the data item collection is observable (it implements <code>INotifyCollectionChanged<\/code>). In this case, it subscribes to the collection change event. If the collection instance is replaced, we need to make sure we remove it by listening to the old collection. We also need to handle creating the item view for each data item. Then bind the item view to the data item. Sometimes we may also want the item view to be different depending on the data item.<\/p>\n<h2>Bindable Layout<\/h2>\n<p>Starting with Xamarin.Forms 3.5.0 pre2, we can use the <code>BindableLayout<\/code> set of <strong>attached properties<\/strong> on any <code>Layout&lt;T&gt;<\/code> view:<\/p>\n<ul>\n<li><em>IEnumerable ItemsSource { get; set; }<\/em><\/li>\n<li><em>DataTemplate ItemTemplate{ get; set; }<\/em><\/li>\n<li><em>DataTemplateSelector ItemTemplateSelector{ get; set; }<\/em><\/li>\n<\/ul>\n<p>These should be familiar to you if you\u2019ve used a <i>ListView<\/i> before.<\/p>\n<p>The simplest usage is to set a data items source. This automatically creates a <em>Label<\/em> child View for every data item in the item source. It makes sense to use it when the data source is a collection of strings:<\/p>\n<p>XAML:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;StackLayout BindableLayout.ItemsSource=\u201d{Binding Sports}\u201d \/&gt;<\/pre>\n<p>C#:<\/p>\n<pre class=\"lang:c# decode:true\">IEnumerable sportsSource = \u2026;\r\nBindableLayout.SetItemsSource(sportsPanel, sportsSource);<\/pre>\n<p>When the default <em>Label<\/em> doesn\u2019t suffice, you can configure a custom template which the Layout View uses to create a child View for every data item in the item source:<\/p>\n<p>XAML:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;StackLayout BindableLayout.ItemsSource=\"{Binding Users}\"&gt;\r\n\u00a0\u00a0\u00a0 &lt;BindableLayout.ItemTemplate&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;DataTemplate&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;StackLayout Orientation=\"Horizontal\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Image Source=\"{Binding Avatar}\" \/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Label Text=\"{Binding Name}\" \/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/StackLayout&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/DataTemplate&gt;\r\n\u00a0 \u00a0\u00a0&lt;\/BindableLayout.ItemTemplate&gt;\r\n&lt;\/StackLayout&gt;<\/pre>\n<p>C#:<\/p>\n<pre class=\"lang:c# decode:true \">DataTemplate useItemTemplate = null;\r\nBindableLayout.SetItemTemplate(usersPanel, userItemTemplate);<\/pre>\n<p>More information on creating and using DataTemplates can be found here: <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/app-fundamentals\/templates\/data-templates\/creating\">Creating a Xamarin.Forms DataTemplate<\/a>.<\/p>\n<p>If you want to have the Layout create the child View depending on the data item, you can then set a <em>DataTemplateSelector<\/em>:<\/p>\n<p>XAML:<\/p>\n<pre class=\"lang:xhtml decode:true\">&lt;FlexLayout BindableLayout.ItemsSource=\"{Binding Users}\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0BindableLayout.ItemTemplateSelector=\"{StaticResource UserItemTemplateSelector}\" \/&gt;<\/pre>\n<p>C#:<\/p>\n<pre class=\"lang:c# decode:true\">DataTemplateSelector userItemTemplateSelector = \u2026;\r\nBindableLayout.SetItemTemplateSelector(usersPanel, userItemTemplateSelector);<\/pre>\n<p>For more information on how to create and use a DataTemplateSelector, please check out <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/app-fundamentals\/templates\/data-templates\/selector\">Creating a Xamarin.Forms DataTemplateSelector<\/a>.<\/p>\n<h3>Vertical List<\/h3>\n<p>When it comes to binding a source of items and displaying it in a vertical list, the ListView has the same features. Its behavior is different and it\u2019s important to understand its limitations:<\/p>\n<ul>\n<li><strong>ListView<\/strong> is inherently a scrollable container. Unless you set a specific height, it takes as much height as possible, because its nature is to display a scrollbar in order to scroll the item views. Having a scrollable view along with other views on a scrollable page is not desirable for your users. There are workarounds to make a ListView display without scrolling. By setting the right height based on the containing views for example, but it\u2019s not pretty or ideal.<\/li>\n<li>The <em>StackLayout<\/em> for example, in contrast, doesn\u2019t have this issue. It takes as much space as it needs for its child elements on the direction of its orientation (vertical\/horizontal), so it computes its size based on its child views.<\/li>\n<li>In <em>ListView<\/em>, the items are selectable and provide a visual feedback when items are pressed\/released. <em>ListView<\/em> can disable selection (<em><u>SelectionMode=\u201dNone\u201d)<\/u><\/em>, but it does not eliminate the highlight when tapping the item. More tweaking is needed and it requires renderers.<\/li>\n<li>You could try to disable the interaction with the a <em>ListView<\/em>. This way both the scrolling and selection won\u2019t be an issue anymore, however this won\u2019t work in the case that you want your users to interact with the items.<\/li>\n<li>Because of its more complex features, the <em>ListView<\/em> is heavier to render than the <em>StackLayout<\/em>, for example.<\/li>\n<\/ul>\n<h3>Upcoming CollectionView<\/h3>\n<p>Like I mentioned earlier, when using the current built-in Layouts available on the framework (<em>StackLayout<\/em>, <em>FlexLayout<\/em>, <em>Grid<\/em>, etc.), the bindable layout functionality is useful when you know that the items source is of few items. The items display must also not be scrollable or selectable. You can always wrap the layout with a <em>ScrollView<\/em>, though in the future a much better option would be to use <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/user-interface\/collectionview\" target=\"_blank\" rel=\"noopener\"><em>CollectionView <\/em><\/a>instead. This does exactly what you need and it&#8217;s more efficient.<\/p>\n<h2>Try it Today!<\/h2>\n<p>I put together a sample app (screenshot below) which uses different bindable layouts in various scenarios that I think it makes sense. Check out <a href=\"https:\/\/github.com\/andreinitescu\/BindableLayoutsApp\">this BindableLayoutsApp<\/a> on Github.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/screenshot.png\"><img decoding=\"async\" class=\"aligncenter wp-image-38498\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/screenshot.png\" alt=\"\" width=\"390\" height=\"700\" \/><\/a>\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guest post Andrei shows off his BindableLayout contribution that is now available in Xamarin.Forms 3.5 to turn any Layout into a layout with a bindable item template.<\/p>\n","protected":false},"author":970,"featured_media":40902,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,367],"tags":[586,409],"class_list":["post-38496","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","category-xamarin-forms","tag-bindable-layout","tag-releases"],"acf":[],"blog_post_summary":"<p>In this guest post Andrei shows off his BindableLayout contribution that is now available in Xamarin.Forms 3.5 to turn any Layout into a layout with a bindable item template.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/38496","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\/970"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=38496"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/38496\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/40902"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=38496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=38496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=38496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}