博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Xamarin.Forms FlexLayout 布局扩展+ 模板扩展+弹性换行
阅读量:4679 次
发布时间:2019-06-09

本文共 6545 字,大约阅读时间需要 21 分钟。

Binding a FlexLayout to a Collection

 

In May we published a doc on the new  control that’s present in Xamarin.Forms 3.0. FlexLayout is a versatile layout control that can arrange its children horizontally and vertically in a stack, and is also capable of wrapping its children if there are too many to fit in a single row or column. It also has options for orientation, alignment, and adapting to various screen sizes.

In the FlexLayout  we outlined some common usage scenarios, with one being a  that are displayed horizontally, which are navigated through by swiping in the appropriate direction. Each item in the catalog is defined inline in XAML as children of the FlexLayout element. This is all very well for static catalog items that are defined by the developer, but what if the data is stored in a collection that’s populated from an external source such as a web service, or a database? This would require the FlexLayout to bind to a collection containing the data. However, this isn’t currently possible as there’s no ItemsSourceproperty (or similar) on the FlexLayout class.

The purpose of this blog post is to demonstrate extending the FlexLayout with ItemsSource and ItemTemplate properties, so that it can bind to data stored in a collection. Note that the implementation will be a minimally viable implementation, rather than a production ready implementation. It demonstrates the simplest approach for binding a FlexLayout to a collection of items.

The sample the code in this blog post comes from can be found on .

Extending FlexLayout

The first step is to create a new class that inherits from FlexLayout, and add the required bindable properties and properties:

public class ExtendedFlexLayout : FlexLayout{    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(        nameof(ItemsSource),         typeof(IEnumerable),         typeof(ExtendedFlexLayout),         propertyChanged: OnItemsSourceChanged);    public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(        nameof(ItemTemplate),         typeof(DataTemplate),         typeof(ExtendedFlexLayout));    public IEnumerable ItemsSource    {        get { return (IEnumerable)GetValue(ItemsSourceProperty); }        set { SetValue(ItemsSourceProperty, value); }    }    public DataTemplate ItemTemplate    {        get { return (DataTemplate)GetValue(ItemTemplateProperty); }        set { SetValue(ItemTemplateProperty, value); }    }    ...}

The code above simply defines ItemsSource and ItemTemplate properties, along with matching BindableProperty versions of them. The ItemTemplateproperty will reference the DataTemplate to apply to each item in the collection referenced by the ItemsSource property. Note that the ItemsSourcePropertyhas a property changed handler defined, named OnItemsSourceChanged. This is where the templated items will be added to the ExtendedFlexLayout:

 

public class ExtendedFlexLayout : FlexLayout{    ...    static void OnItemsSourceChanged(BindableObject bindable, object oldVal, object newVal)    {        IEnumerable newValue = newVal as IEnumerable;        var layout = (ExtendedFlexLayout)bindable;        layout.Children.Clear();        if (newValue != null)        {            foreach (var item in newValue)            {                layout.Children.Add(layout.CreateChildView(item));            }        }    }    View CreateChildView(object item)    {        ItemTemplate.SetValue(BindableObject.BindingContextProperty, item);        return (View)ItemTemplate.CreateContent();    }}

The OnItemsSourceChanged method iterates through the collection referenced by the ItemsSource property, and calls the CreateChildView method for each item. This method sets the binding context of the ItemTemplate to the item, loads the DataTemplate referenced by the ItemTemplate property, and returns it to the OnItemsSourceChanged method, where the templated item is added as a child of the ExtendedFlexLayout.

Consuming the ExtendedFlexLayout

The ExtendedFlexLayout can be consumed in XAML as follows:

This ExtendedFlexLayout instance sets its ItemsSource property to a collection named Monkeys, which exists on the view model the page binds to. It also sets its ItemTemplate property to an inline DataTemplate that binds different views to different properties of each Monkey in the Monkeys collection. The result is, as per the FlexLayout , there are three items displayed that can be navigated through by swiping in the appropriate direction:

Simulator Screen Shot - iPhone 8 - 2018-06-14 at 11.57.59

The difference between the FlexLayout  and this approach is that in the guide each item is declared inline in XAML. Here, each item comes from a collection that the ExtendedFlexLayout binds to. The advantage of this approach is that it allows the displayed data to be populated from an external source, such as a web service or a database.

Issues

As I previously mentioned, the ExtendedFlexLayout is a minimally viable implementation. While it works for the scenario outlined here, it’s quite limited:

  • It doesn’t respond to the bound collection changing at runtime (think ObservableCollection). Instead, the entire collection must be available when binding occurs.
  • It doesn’t respond to binding context changes. The binding context must be set when binding occurs, and can’t change.
  • It only permits a single defined DataTemplate to be used. It doesn’t allow a DataTemplateSelector to choose a DataTemplate at runtime based on the value of a bound property.
  • There’s no UI virtualisation. For large collections, the ExtendedFlexLayout could consume a lot of memory.

I’ll explore some of these issues in future blog posts.

Summary

This blog post has explained how to extend the FlexLayout with ItemsSource and ItemTemplate properties, so that it can bind to data stored in a collection. However, the ExtendedFlexLayout is currently a minimally viable implementation. My next blog post will look at extending the implementation with additional functionality.

The sample this code comes from can be found on .

转载于:https://www.cnblogs.com/mschen/p/10430389.html

你可能感兴趣的文章
Oracle-建表course
查看>>
Java常用的非受检异常
查看>>
HDOJ-2054
查看>>
centos7安装eclipse
查看>>
Web:AJAX的详解
查看>>
两种比较器Comparable 和 Comparator
查看>>
S2JDBC テーブルを利用した独自仕様のid採番メソッド
查看>>
P3698 [CQOI2017]小Q的棋盘
查看>>
动态规划入门 洛谷P2409 Y的积木
查看>>
【第一季】CH04_FPGA设计Verilog基础(一)Enter a post title
查看>>
算法的基本概念
查看>>
2018-2019-1 20189206 《Linux内核原理与分析》第八周作业
查看>>
股票买卖问题
查看>>
Matlab+ModelSim“傻瓜化”设计数字滤波器
查看>>
直接数字频率合成器(DDS)基本原理
查看>>
转载:【小作品】STM32无线WIFI视频小车制作剖析(上)
查看>>
echarts学习网站
查看>>
原生的js轮播图
查看>>
字符串操作、文件操作,英文词频统计预处理
查看>>
telnet不能用!!!提示:-bash: telnet: command not found
查看>>