XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

2019/04/25

使用 CollectionView 建立一個能以 GridView 呈現的效果

使用 CollectionView 建立一個能以 GridView 呈現的效果

CollectionView 現階段還是在 Preview 階段,當 Xamarin.Forms 4.0 (現階段 Xamarin.Forms 的版本是 3.6) 正式推出的時候,將可以使用這個 CollectionView 檢視。這個檢視除了具有 ListView 的功能之外,它還可以使用 GridView 的模式來顯示出每筆資料,現在,就來實際建立這個專案來體驗設計過程吧。
該文件的專案原始碼可以透過 GitHub 來取得

建立一個 使使用 FlexLayout 專案

  • 開啟 Visual Studio 2019 程式
  • 當 Visual Studio 2019 開始 視窗 出現之後,請點選左下角的 [建立新專案] 選項
  • 當 [建立新專案] 對話窗出現之後,請在中間最上方的搜尋文字輸入盒中輸入 [prism] 關鍵字,搜尋所有與 Prism 有關的專案樣板
  • 請選擇 [Prism Blank App (Xamarin.Forms)] 這個專案樣板
  • 當出現 [設定新的專案] 對話窗,請在 [專案名稱] 輸入 [XF3002]
  • 最後點選該對話窗右下方的 [建立] 按鈕
  • 現在將會看到 [PRISM PROJECT WIZARD] 對話窗,請勾選 ANDROID, iOS 這兩個行動裝置平台,接著在底下 [Container] 下拉選單,選擇 Unity 項目
  • 最後,點選 [CREATE PROJECT] 按鈕,以便產生 Xamarin.Forms 專案

安裝需要用到的 PropertyChanged.Fody NuGet 套件

  • 當這個 Xamarin.Forms 專案建立成功之後,請在該方案中,找到 Xamarin.Forms 使用的專案(這是一個 .NET Standard 類別庫,簡稱為 SCL ),請在該專案中,使用滑鼠右擊 [相依性] 節點,選擇 [管理 NuGet 套件] 選項
  • 在 [NuGet: XXX] 視窗中,點選 [瀏覽] 標籤頁次,並且在下方的搜尋文字輸入盒中,輸入 [propertychanged.fody] 關鍵字,搜尋出這個 NuGet 套件
  • 當出現 [PropertyChanged.Fody] NuGet 套件,請點選該套件,並且點選右方的 [安裝] 按鈕,將這個套件安裝到 Xamarin.Forms 專案內
  • 請查看 Xamarin.Forms 專案內,並沒有 [FodyWeavers.xml] 這個檔案,因此,使用滑鼠右擊 Xamarin.Forms 專案節點,選擇 [建置] 選項
  • 當建置完成之後,在這個 Xamarin.Forms 專案內將會出現 [FodyWeavers.xml] 檔案

安裝需要用到的 Xamarin.Essentials NuGet 套件

  • 在 [NuGet: XXX] 視窗中,搜尋文字輸入盒中,輸入 [Xamarin.Essentials] 關鍵字,搜尋出這個 NuGet 套件
  • 當出現 [Xamarin.Essentials] NuGet 套件,請點選該套件,並且點選右方的 [安裝] 按鈕,將這個套件安裝到 Xamarin.Forms 專案內

修正因為安裝 Xamarin.Essentials 帶來的錯誤

現在,可以從 Visual Studio 2019 的錯誤視窗中,看到底下的錯誤訊息
錯誤    NU1107    偵測到 Xamarin.Android.Support.Compat 有版本衝突。請將 Xamarin.Android.Support.Compat 28.0.0.1 直接安裝/參考到專案 XF3002.Android 來解決此問題。 
 XF3002.Android -> XF3002 -> Xamarin.Essentials 1.1.0 -> Xamarin.Android.Support.Compat (>= 28.0.0.1) 
 XF3002.Android -> Xamarin.Android.Support.Design 27.0.2.1 -> Xamarin.Android.Support.Compat (= 27.0.2.1).    XF3002.Android    D:\Vulcan\GitHub\XCourse19\XF3002\XF3002\XF3002.Android\XF3002.Android.csproj    1
想要解決此一問題:
  • 使用滑鼠右擊方案節點(方案總管最上方的那個節點),選擇 [管理方案的 NuGet 套件]
  • 點選 [更新] 標籤頁次
  • 勾選該標籤頁次內的所有項目
  • 點選右上方的更新按鈕,就可以升級這些套件到最新版本了

升級 Xamarin.Forms 套件到 4.0 版本

  • 同樣的,使用滑鼠右擊方案節點(方案總管最上方的那個節點),選擇 [管理方案的 NuGet 套件]
  • 點選 [已安裝] 標籤頁次
  • 點選 [Xamarin.Forms] 套件項目
  • 勾選 [包括搶鮮版] 檢查盒,要求顯示搶鮮版的套件清單
  • 在右方的 Xamarin.Forms 套件清單中,勾選所有的專案
  • 在下方的版本下拉選單中,選擇 4.0 以上的版本,現階段只能夠看到 4.0.0.346134-pre9 這個版本
  • 點選右下方 [安裝] 按鈕,將這個 4.0 的 Xamarin.Forms 套件安裝到所有專案內

建立資料模型

  • 滑鼠右擊 Xamarin.Forms 專案,選擇 [加入] > [新增資料夾]
  • 將新增資料夾的名稱設定為 [Models]
  • 滑鼠右擊剛剛建立的 [Models] 資料夾,選擇 [加入] > [類別]
  • 在 [新增項目] 對話窗下方的 [名稱] 欄位中,輸入 [MyData]
  • 點選右下方的 [新增] 按鈕
  • 將底下程式碼填入到這個新建立的類別檔案內
C Sharp / C#
public class MyData : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string Name { get; set; }
    public int OrderId { get; set; }
}

修正該 Android 專案的 MainActivity.cs

因為現階段 CollectionView 還是在預覽階段,所以,需要在原生專案的進入點內,要執行 Xamarin.Forms.Forms.Init 這個方法前,要增加先執行底下的方法。
  • 打開 [MainActivity.cs] 檔案
  • 將第 18 行,此行沒有任何程式碼,在此加入這個 C# 敘述 Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");

建立使用 CollectionView 的頁面與商業邏輯

  • 在 [Views] 資料夾內,打開 [MainPage.xaml] 檔案
  • 修正使用底下的 XAML 語言宣告
在這裡的 CollectionView 將會透過 [ItemsSource] 這個可綁定屬性,從 ViewModel 物件內取得要顯示的清單集合資料,並且使用 [SelectionMode] 屬性,設定使用者僅能夠使用單選的方式來選取,最後透過 [SelectionChangedCommand] 這個命令,綁定到 ViewModel 內的 ICommand 屬性,也就是當使用者點選任一項目之後,將會觸發這個命令。
在 CollectionView 內,可以使用 [CollectionView.ItemsLayout] 來設定此次要顯示的資料格式,在這裡將會使用 [GridItemsLayout] 這個屬性來指定使用 GridView 的模式來呈現,並且是以垂直方式來顯示資料。
xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XF3002.Views.MainPage"
             Title="CollectionView 的應用練習">

    <StackLayout
        >
        <CollectionView
            x:Name="cv"
            ItemsSource="{Binding myItemList}"
            SelectionMode="Single"
            SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
            SelectionChangedCommand="{Binding SelectionChangedCommand}"
            >
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical" Span="2" />
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Frame BorderColor="LightGray" CornerRadius="3" HasShadow="False">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="70"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="150"/>
                            </Grid.ColumnDefinitions>
                            <Label
                                HorizontalOptions="Start"
                                Text="{Binding Name}"
                                FontAttributes="Bold"
                                FontSize="20"/>
                            <Label
                                HorizontalOptions="End" VerticalOptions="End"
                                Text="{Binding OrderId}"
                                TextColor="Red"
                                FontSize="16"/>
                        </Grid>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

</ContentPage>
  • 在 [ViewModels] 資料夾內,打開 [MainPageViewModel.xaml] 檔案
  • 修正使用底下的 C# 程式碼
C Sharp / C#
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XF3002.ViewModels
{
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using Prism.Events;
    using Prism.Navigation;
    using Prism.Services;
    using XF3002.Models;

    public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ObservableCollection<MyData> myItemList { get; set; } = new ObservableCollection<MyData>();
        public MyData SelectedItem { get; set; }
        public int GridItemsLayoutSpan { get; set; } = 2;
        public DelegateCommand SelectionChangedCommand { get; set; }
        private readonly INavigationService navigationService;
        private readonly IPageDialogService dialogService;

        public MainPageViewModel()
        {
            ReadData();
        }
        public MainPageViewModel(INavigationService navigationService, IPageDialogService dialogService)
        {
            this.navigationService = navigationService;
            this.dialogService = dialogService;
            SelectionChangedCommand = new DelegateCommand(() =>
            {
                dialogService.DisplayAlertAsync("Info", SelectedItem.Name, "OK");
            });
        }

        public void OnNavigatedFrom(INavigationParameters parameters)
        {
        }

        public void OnNavigatedTo(INavigationParameters parameters)
        {
            ReadData();
        }

        public void OnNavigatingTo(INavigationParameters parameters)
        {
        }
        public void ReadData()
        {
            int cc = 1;
            for (int i = 0; i < 10; i++)
            {
                myItemList.Add(new MyData() { Name = "Baboon", OrderId=cc++ });
                myItemList.Add(new MyData() { Name = "Capuchin Monkey", OrderId = cc++ });
                myItemList.Add(new MyData() { Name = "Blue Monkey", OrderId = cc++ });
                myItemList.Add(new MyData() { Name = "Squirrel Monkey", OrderId = cc++ });
                myItemList.Add(new MyData() { Name = "Golden Lion Tamarin", OrderId = cc++ });
                myItemList.Add(new MyData() { Name = "Howler Monkey", OrderId = cc++ });
                myItemList.Add(new MyData() { Name = "Japanese Macaque", OrderId = cc++ });
            }
        }
    }
}

執行結果




沒有留言:

張貼留言