XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2016/11/10

Xamarin.Forms 使用具有 GridView 特性的 ListView

傳統上 Xamarin.Forms 並沒有提供類似 GridView 這樣的控制項,也就是可以使用多 Column 的方式來顯示集合資料,但是其他的行為與 ListView 一樣。
在這份筆記中,將會測試與使用 DLToolkit.Forms.Controls.FlowListView 這個 NuGet 套件,就可以達成使用 GridView 控制項的效果。
要使用這個功能,您需要在方案中加入這個 DLToolkit.Forms.Controls.FlowListView NuGet 套件到所有的專案內;下面螢幕截圖為實際執行結果。
XFHListView
範例專案

需要安裝 NuGet 套件

要完成這個筆記中的效果,你需要在方案中安裝底下的 NuGet 套件
Xamarin.FFImageLoading.Forms
DLToolkit.Forms.Controls.FlowListView

範例說明

首先,需要定義這個集合的資料模型。
在這個,建立了一個 SampleItems1 資料模型,裡面有 Title / Color / ImageUrl 這三個屬性。
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;

namespace XFHListView.Models
{
    public class SampleItems1 : BindableBase
    {

        #region Title
        private string _Title;
        /// <summary>
        /// Title
        /// </summary>
        public string Title
        {
            get { return this._Title; }
            set { this.SetProperty(ref this._Title, value); }
        }
        #endregion


        #region Color
        private Color _Color;
        /// <summary>
        /// Color
        /// </summary>
        public Color Color
        {
            get { return this._Color; }
            set { this.SetProperty(ref this._Color, value); }
        }
        #endregion


        #region ImageUrl
        private string _ImageUrl;
        /// <summary>
        /// ShowImage
        /// </summary>
        public string ImageUrl
        {
            get { return this._ImageUrl; }
            set { this.SetProperty(ref this._ImageUrl, value); }
        }
        #endregion

        public SampleItems1()
        {

        }
    }
}
接著需要在 ViewModel 內定義所有資料綁定的集合資料,並且要進行集合資料的初始化,可以參考底下程式碼。
在這個 ViewModel 內,集合資料將會使用 ObservableCollection<SampleItems1> 型別,並且儲存在 MyDatas 這個物件內。
在建構式內,呼叫了 Init() 方法,針對 MyDatas 進行產生實際物件並且進行資料初始化。
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using XFHListView.Models;

namespace XFHListView.ViewModels
{
    public class SimpleSamplePageViewModel : BindableBase
    {
        #region MyDatas
        private ObservableCollection<SampleItems1> _MyDatas;
        /// <summary>
        /// MyDatas
        /// </summary>
        public ObservableCollection<SampleItems1> MyDatas
        {
            get { return _MyDatas; }
            set { SetProperty(ref _MyDatas, value); }
        }
        #endregion

        #region 使用者點選項目
        private SampleItems1 _使用者點選項目;
        /// <summary>
        /// 使用者點選項目
        /// </summary>
        public SampleItems1 使用者點選項目
        {
            get { return this._使用者點選項目; }
            set { this.SetProperty(ref this._使用者點選項目, value); }
        }
        #endregion

        public DelegateCommand 使用者點選Command { get; set; }

        public readonly IPageDialogService _dialogService;
        public SimpleSamplePageViewModel(IPageDialogService dialogService)
        {

            _dialogService = dialogService;
            Init();

            使用者點選Command = new DelegateCommand(() =>
              {
                  _dialogService.DisplayAlertAsync("訊息", $"你選取的是 {使用者點選項目.Title}", "OK");
              });
        }

        public void Init()
        {
            MyDatas = new ObservableCollection<SampleItems1>();

            var howMany = new Random().Next(100, 500);

            for (int i = 0; i < howMany; i++)
            {
                MyDatas.Add(new SampleItems1() { Title = string.Format("項目 {0}", i) });
            }
        }
    }
}
有的 Model / ViewModel,接下來,就是要定義 View,可以參考底下 XAML 。
這個頁面 XAML 內容相當的簡單,根項目為 ContentPage,並且其兒子為 FlowListView;不過,由於這個 FlowListView 控制項並不是 Xamarin.Forms 預設命名空間所提供的,因此,需要在跟項目內另外定義一個命名空間 xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView",這樣,就可以使用前置詞 flv 來引用 FlowListView 這個控制項。
FlowListView 這個控制項內,使用了 FlowColumnCount="3" 宣告了這個 GridView 效果共有三個 Column,並且每筆紀錄並沒有使用分隔線,這是使用了這個宣告:SeparatorVisibility="None"
另外,使用了 HasUnevenRows="False" 設定每筆紀錄都是等高;當使用者點選了清單內的某個項目,可以使用 FlowItemTappedCommand 來綁定 ViewModel 內的某個 DelegateCommand ,就可以在 ViewModel 內撰寫相關點擊後的處理邏輯;而使用者點選後的項目,也會透過 FlowLastTappedItem 這個屬性,將其綁定到 ViewModel 內的某個屬性,也就是說,當使用者點選某個項目,就可以透過該 ViewModel 內的屬性,取得使用者當時點選的項目內容;最後,該 FlowListView 要顯示的資料清單內容,將會透過 FlowItemsSource屬性來進行資料綁定。
最後,與 ListView 相同,每筆資料,可以透過 FlowListView.FlowColumnTemplate 來設定這些資料項目要使用何種格式來顯示。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="XFHListView.Views.SimpleSamplePage"
             xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
             Title="簡單範例">

    <flv:FlowListView
        FlowColumnCount="3"
        SeparatorVisibility="None"
        HasUnevenRows="False"
        FlowItemTappedCommand="{Binding 使用者點選Command}"
        FlowLastTappedItem="{Binding 使用者點選項目}"
        FlowItemsSource="{Binding MyDatas}" HeightRequest="100"
        >
        <flv:FlowListView.FlowColumnTemplate>
            <DataTemplate>
                <Label HorizontalOptions="Fill" VerticalOptions="Fill" 
                        XAlign="Center" YAlign="Center" Text="{Binding Title}"/>
            </DataTemplate>
        </flv:FlowListView.FlowColumnTemplate>

    </flv:FlowListView>
</ContentPage>

沒有留言:

張貼留言