XamarinForms 系列課程

特別說明

2016/12/04

在 Xamarin.Forms 使用旋轉木馬 CarouselView 控制項,可以左右翻轉

當您需要讓使用者可以在螢幕上,透過手勢左右滑動,看到不同的資料內容,如下圖所呈現的效果。

這個時候,您可以選擇使用旋轉木馬 CarouselView 這個控制項,要使用這個控制項,您需在方案中,加入這個 NuGet 套件到所有的專案內,此時,請在 NuGet 套件安裝視窗中,輸入 Xamarin.Forms.CarouselView ,但是,你將無法看到這個套件,請將旁邊的 包含搶鮮版 檢查盒打勾,就會看到這個套件了。
參考專案原始碼
https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFCarouselView
參考文章
https://blog.xamarin.com/flip-throug
h-items-with-xamarin-forms-carouselview/


正在嘗試針對專案 'XFCarouselView' 及目標 '.NETPortable,Version=v4.5,Profile=Profile259' 收集封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性資訊
收集相依性資訊花費了 5.12 sec
嘗試解析具有 DependencyBehavior 'Lowest' 之封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性
解析相依性資訊花費了 0 ms
正在解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作
已解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作


正在嘗試針對專案 'XFCarouselView.Droid' 及目標 'MonoAndroid,Version=v7.0' 收集封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性資訊
收集相依性資訊花費了 24.33 sec
嘗試解析具有 DependencyBehavior 'Lowest' 之封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性
解析相依性資訊花費了 0 ms
正在解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作
已解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作


正在嘗試針對專案 'XFCarouselView.iOS' 及目標 'Xamarin.iOS,Version=v1.0' 收集封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性資訊
收集相依性資訊花費了 16.53 sec
嘗試解析具有 DependencyBehavior 'Lowest' 之封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的相依性
解析相依性資訊花費了 0 ms
正在解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作
已解析安裝封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 的動作
正在還原 'XFCarouselView.UWP' 封裝。
正在還原 C:\Vulcan\GitBook\Temp\XFCarouselView\XFCarouselView\XFCarouselView.UWP\project.json 的封裝...
  GET https://api.nuget.org/v3-flatcontainer/xamarin.forms.carouselview/index.json
  OK https://api.nuget.org/v3-flatcontainer/xamarin.forms.carouselview/index.json 973ms
  GET https://api.nuget.org/v3-flatcontainer/xamarin.forms.carouselview/2.3.0-pre2/xamarin.forms.carouselview.2.3.0-pre2.nupkg
  OK https://api.nuget.org/v3-flatcontainer/xamarin.forms.carouselview/2.3.0-pre2/xamarin.forms.carouselview.2.3.0-pre2.nupkg 921ms
正在安裝 Xamarin.Forms.CarouselView 2.3.0-pre2。
已成功完成 'XFCarouselView.UWP' 的封裝還原。
正在從 'nuget.org' 擷取封裝 'Xamarin.Forms.CarouselView 2.3.0-pre2'。
正在將封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 加入資料夾 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages'
已將封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 加入資料夾 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages'
已將封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 加入 'packages.config'
已成功將 'Xamarin.Forms.CarouselView 2.3.0-pre2' 安裝到 XFCarouselView
執行 NuGet 動作花費了 1.23 sec
在 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages' 中找到封裝 'Xamarin.Forms.CarouselView 2.3.0-pre2'。
封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 已經存在於資料夾 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages'
已將封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 加入 'packages.config'
已成功將 'Xamarin.Forms.CarouselView 2.3.0-pre2' 安裝到 XFCarouselView.Droid
執行 NuGet 動作花費了 4.22 sec
在 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages' 中找到封裝 'Xamarin.Forms.CarouselView 2.3.0-pre2'。
封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 已經存在於資料夾 'C:\Vulcan\GitBook\Temp\XFCarouselView\packages'
已將封裝 'Xamarin.Forms.CarouselView.2.3.0-pre2' 加入 'packages.config'
已成功將 'Xamarin.Forms.CarouselView 2.3.0-pre2' 安裝到 XFCarouselView.iOS
執行 NuGet 動作花費了 840.61 ms
Writing lock file to disk. Path: C:\Vulcan\GitBook\Temp\XFCarouselView\XFCarouselView\XFCarouselView.UWP\project.lock.json
正在產生 MSBuild 檔案 XFCarouselView.UWP.nuget.targets。
已成功將 'Xamarin.Forms.CarouselView 2.3.0-pre2' 安裝到 XFCarouselView.UWP
========== 已完成 ==========
經過時間: 00:00:57.0114984
要了要能夠在 CarouselView 內可以使用 ViewModel 的 ICommand 來綁定點選事件,請也在所有的專案內,安裝這個套件 Behaviors.Forms
在這裡,將建立一個專案,並且將上述兩個套件,安裝到所有的專案內,接著,在 View 中,定義底下的 XAML。
在這裡加入了兩個命名空間 cv 用來指向 旋轉木馬控制項之用,behaviors 用來指向擴充的行為定義之用。
在 CarsouselView 控制項內,因為本身沒有提供相關 ICommand 可綁定屬性,因此,透過了行為來定義了,當 CarsoulerView 的資料有更換的時候,也就是 ItemSelected 事件有被驅動的時候,就會執行 CarouselView點選 這個 Command,這是透過了底下的 XAML宣告,
            <cv:CarouselView.Behaviors>
                <behaviors:EventHandlerBehavior EventName="ItemSelected">
                    <behaviors:InvokeCommandAction Command="{Binding CarouselView點選Command}"
                                                  />
                    <!--<behaviors:InvokeCommandAction Command="{Binding CarouselView點選Command}"
                                                   Converter="{StaticResource SelectedItemChangedEventArgsConverter}"/>-->
                </behaviors:EventHandlerBehavior>
            </cv:CarouselView.Behaviors>
底下是完整的 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"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
             xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
             xmlns:local="clr-namespace:XFCarouselView"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="XFCarouselView.Views.MainPage"
             Title="MainPage"
             x:Name="ThisPage"
             >

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:SelectedItemChangedEventArgsConverter x:Key="SelectedItemChangedEventArgsConverter" />
        </ResourceDictionary>
    </ContentPage.Resources> 


    <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
        <Label Text="{Binding Title}" />
        <cv:CarouselView x:Name="CarouselZoos"
            ItemsSource="{Binding Zoos}" 
            HorizontalOptions="Fill"
            HeightRequest="180" WidthRequest="300">
            <cv:CarouselView.Behaviors>
                <behaviors:EventHandlerBehavior EventName="ItemSelected">
                    <behaviors:InvokeCommandAction Command="{Binding CarouselView點選Command}"
                                                  />
                    <!--<behaviors:InvokeCommandAction Command="{Binding CarouselView點選Command}"
                                                   Converter="{StaticResource SelectedItemChangedEventArgsConverter}"/>-->
                </behaviors:EventHandlerBehavior>
            </cv:CarouselView.Behaviors>
            <cv:CarouselView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Image Grid.RowSpan="2" Aspect="AspectFill" Source="{Binding ImageUrl}"/>
                        <StackLayout Grid.Row="1" BackgroundColor="#80000000" Padding="12">
                            <Label TextColor="White" Text="{Binding Name}" FontSize="16" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
                        </StackLayout>
                    </Grid>
                </DataTemplate>
            </cv:CarouselView.ItemTemplate>
        </cv:CarouselView>
        <Label Text="{Binding Title}" />
    </StackLayout>
</ContentPage>
ViewModel 的程式碼如下
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using Prism.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;
using XFCarouselView.Models;

namespace XFCarouselView.ViewModels
{
    public class MainPageViewModel : BindableBase, INavigationAware
    {
        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        #region Zoos
        private ObservableCollection<Zoo> _Zoos;
        /// <summary>
        /// Zoos
        /// </summary>
        public ObservableCollection<Zoo> Zoos
        {
            get { return _Zoos; }
            set { SetProperty(ref _Zoos, value); }
        }
        #endregion

        private readonly INavigationService _navigationService;

        public readonly IPageDialogService _dialogService;
        public MainPageViewModel(INavigationService navigationService, IPageDialogService dialogService)
        {

            _dialogService = dialogService;
            _navigationService = navigationService;
            Zoos = new ObservableCollection<Zoo>
            {
                new Zoo
                {
                ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/23c1dd13-333a-459e-9e23-c3784e7cb434/2016-06-02_1049.png",
                Name = "Woodland Park Zoo"
                },
                new Zoo
                {
                ImageUrl =    "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/6b60d27e-c1ec-4fe6-bebe-7386d545bb62/2016-06-02_1051.png",
                Name = "Cleveland Zoo"
                },
                new Zoo
                {
                ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/e8179889-8189-4acb-bac5-812611199a03/2016-06-02_1053.png",
                Name = "Phoenix Zoo"
                }
            };

            CarouselView點選Command = new DelegateCommand<SelectedItemChangedEventArgs>( x =>
            {
                var foo = x.SelectedItem as Zoo;
                //await _dialogService.DisplayAlertAsync("Infor", $"Selected {foo.Name}", "OK");

                Title = $"Selected {foo.Name}";
            });
        }

        public DelegateCommand<SelectedItemChangedEventArgs> CarouselView點選Command { get; set; }

        public DelegateCommand CarouselViewTest點選Command { get; set; }


        public void OnNavigatedFrom(NavigationParameters parameters)
        {
        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {
            if (parameters.ContainsKey("title"))
                Title = (string)parameters["title"] + " and Prism";
        }
    }
}

1 則留言:

  1. 請問這個可以改成套ImageButton嗎

    回覆刪除