XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

2016/11/07

Xamarin.Forms 的轉換應用

什麼是轉換 Transform
在 Xamarin.Forms 中的每個 View,都可以使用 Transform,其中透過這些轉換屬性定義,可以將特定 View 的某個座標空間之相關點,經過數學運算,對應或轉換到另一個座標空間。經過這樣的處理,此時,View 就會在螢幕上呈現在不同的位置與不同樣棒,如同下圖所示。
XFTransform

XAML 轉換使用說明

在這個範例中,並不需要透過任何 ViewModel 或者 Code Behind 的C#程式碼,就可以做到這樣的效果。
在底下的 XAML 範例中,將會透過資料繫結的方式,只要使用者變更了 Slider 的值,就會變更頁面上的 Frame 的座標轉換。
<?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="XFTransforms.Views.MainPage"
             Title="MainPage"> 
  <Grid HorizontalOptions="Fill" VerticalOptions="Fill">
        <Frame x:Name="frame" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" OutlineColor="Accent">
            <Label Text="這是Xamarin.Forms" FontSize="Large" />
        </Frame>
        <StackLayout
          HorizontalOptions="Fill" VerticalOptions="End">
            <Grid
                HorizontalOptions="Fill" VerticalOptions="Center"
                >
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Slider Grid.Row="0" Grid.Column="0" Minimum="-200" Maximum="200" Value="{Binding Source={x:Reference frame}, Path=TranslationX}" />
                <Slider Grid.Row="0" Grid.Column="1" Minimum="-200" Maximum="200" Value="{Binding Source={x:Reference frame}, Path=TranslationY}" />
                <Slider Grid.Row="1" Grid.Column="0" Minimum="-10" Maximum="10" Value="{Binding Source={x:Reference frame}, Path=Scale}" />
                <Slider Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="360" Value="{Binding Source={x:Reference frame}, Path=Rotation}" />
                <Slider Grid.Row="2" Grid.Column="0" Minimum="-1" Maximum="2" Value="{Binding Source={x:Reference frame}, Path=AnchorX}" />
                <Slider Grid.Row="2" Grid.Column="1" Minimum="-1" Maximum="2" Value="{Binding Source={x:Reference frame}, Path=AnchorY}" />
                <Slider Grid.Row="3" Grid.Column="0" Maximum="360" Value="{Binding Source={x:Reference frame}, Path=RotationX}" />
                <Slider Grid.Row="3" Grid.Column="1" Maximum="360" Value="{Binding Source={x:Reference frame}, Path=RotationY}" />
            </Grid>
        </StackLayout>
    </Grid>
</ContentPage>

2016/11/06

如何在 Xamarin.Forms 使用 BindingContext 設定 ListView 的資料來源並且綁定

在這份筆記中,將會描述如何建立一個 ViewModel,但是,不使用 Prism 這種框架來直接進行 ViewModel 的綁定,而是透過了 Code Behind 中,設定了 BindingContext的方式,讓整個頁面具有這個 ViewModel,可用於相關 View 資料綁定之用。
底下為這個範例用到的 ViewModel
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sampleListView
{

    public class ViewModel
    {
        public ObservableCollection<someDataClass> MyItemList { get; set; }

        public ViewModel()
        {
            MyItemList = new ObservableCollection<someDataClass>()
            {
                new someDataClass { sometext="sometext1", othertext="othertext1" },
                new someDataClass { sometext="sometext2", othertext="othertext2" },
                new someDataClass { sometext="sometext3", othertext="othertext3" },
                new someDataClass { sometext="sometext4", othertext="othertext4" },
            };
        }
    }

    public class someDataClass
    {
        public string sometext { get; set; }
        public string othertext { get; set; }
    }
}
接著在這個頁面的 Code Behind 中,使用了 this.BindingContext = new ViewModel(); 敘述,將 ViewMdoel 設定頁面的 BindingContext 上。
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = new ViewModel();
        }
    }
若不想要透過 Code Behind 的方式來設定 BindingContext,也可以在 XAML 中,直接透過底下方式來宣告。
首先,宣告一個命名空間 xmlns:local="clr-namespace:sampleListView" 名稱為 local,這個命名空間可以指向 ViewModel 類別所在的命名空間。接著使用 Property-Element 表示方式,宣告了 ContentPage.BindingContext 這個屬性的值為 local:ViewModel />
<?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:local="clr-namespace:sampleListView"
             x:Class="sampleListView.MainPage">

    <ContentPage.BindingContext>
        <local:ViewModel />
    </ContentPage.BindingContext>

    <ListView x:Name="listView" ItemsSource="{Binding MyItemList}" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="{Binding sometext}" Detail="{Binding othertext}"></TextCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

參考專案

2016/11/05

在 Xamarin.Forms中,使用 ZXing.Net.Mobile 產生各種條碼圖片

若想要在 Xamarin.Forms 應用程式中,產生各種一維或者二維條碼圖片,可以按這這篇文章的設定步驟,就可以讓 Xamarin.Forms 的應用程式顯示這些圖片。
在 ZXing.Net.Mobile 環境中,支援底下的條碼
    public enum BarcodeFormat
    {
        AZTEC = 1,
        CODABAR = 2,
        CODE_39 = 4,
        CODE_93 = 8,
        CODE_128 = 16,
        DATA_MATRIX = 32,
        EAN_8 = 64,
        EAN_13 = 128,
        ITF = 256,
        MAXICODE = 512,
        PDF_417 = 1024,
        QR_CODE = 2048,
        RSS_14 = 4096,
        RSS_EXPANDED = 8192,
        UPC_A = 16384,
        UPC_E = 32768,
        All_1D = 61918,
        UPC_EAN_EXTENSION = 65536,
        MSI = 131072,
        PLESSEY = 262144,
        IMB = 524288
    }
  • 建置一個 Prism 的 Xamarin.Forms 專案
  • 在方案中啟動 NuGet 安裝工具,搜尋套件 ZXing.Net.Mobile.Forms,將這個套件安裝到所有的專案內。
  • 修改首頁頁面,如底下的 XAML
    底下的 XAML 首先命名了兩個額外的命名空間 Zxing / ZxingCommon,前者是要了要指向可以使用產生條碼圖片的控制項,而後者,則是為了要使用 BarcodeOptions 這個物件,用來設定條碼的大小等特性。
    要顯示條碼,可以使用 ZXingBarcodeImageView 控制項,其中這個 Element 內的 Attribute 屬性,是用來設定要顯示的條碼類型,而該條碼的原始文字內容,需要使用 BarcodeValue 這個值來設定。
    若要設定該條碼產生的圖片大小,則需要使用 Property-Element 的表示方式,設定 ZXingBarcodeImageView.BarcodeOptions 這個屬性值;而當要設定這個屬性值的時候,我們需要使用另外一個命名空間 ZxingCommon 來設定 EncodingOptions 這個物件屬性,在這裡,使用了 Width & Height 這兩個屬性值。
<?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"
             xmlns:Zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             xmlns:ZxingCommon="clr-namespace:ZXing.Common;assembly=zxing.portable"
             x:Class="XFGenBarcode.Views.MainPage"
             Title="MainPage">
    <StackLayout x:Name="stacklayout" HorizontalOptions="Center" VerticalOptions="Center">
        <Label Text="{Binding Title}" />
        <Zxing:ZXingBarcodeImageView
            BarcodeFormat="QR_CODE"
            Margin="10"
            WidthRequest="300" HeightRequest="300"
            BarcodeValue="多奇數位創意有限公司 Vulcan Lee">
            <Zxing:ZXingBarcodeImageView.BarcodeOptions>
                <ZxingCommon:EncodingOptions Width="300" Height="300" />
            </Zxing:ZXingBarcodeImageView.BarcodeOptions>
        </Zxing:ZXingBarcodeImageView>
        <Zxing:ZXingBarcodeImageView
            HorizontalOptions="Fill" VerticalOptions="Fill"
            WidthRequest="300" HeightRequest="70"
            BarcodeFormat="CODE_128"
            BarcodeValue="DoggyVulcan123">
            <Zxing:ZXingBarcodeImageView.BarcodeOptions>
                <ZxingCommon:EncodingOptions Width="300" Height="40" />
            </Zxing:ZXingBarcodeImageView.BarcodeOptions>
        </Zxing:ZXingBarcodeImageView>
    </StackLayout>
</ContentPage>
  • 若想要在 Code Behind 中使用產生條碼圖片,可以參考底下程式碼
using Xamarin.Forms;
using ZXing.Net.Mobile.Forms;

namespace XFGenBarcode.Views
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            var barcode = new ZXingBarcodeImageView
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
            };
            barcode.BarcodeFormat = ZXing.BarcodeFormat.QR_CODE;
            barcode.BarcodeOptions.Width = 300;
            barcode.BarcodeOptions.Height = 300;
            barcode.BarcodeOptions.Margin = 10;
            barcode.BarcodeValue = "ZXing.Net.Mobile";

            stacklayout.Children.Add(barcode);
        }
    }
}
  • 接下來,就可以直接在模擬器上執行,就可以看到執行結果囉。
    條碼顯示結果

參考文件與範例專案原始碼

2016/11/04

在 Xamarin.Forms專案中,建置一維或二維條碼掃描功能

請依照底下步驟說明,建置一個可以進行條碼或者QR Code掃瞄功能的應用程式
  1. 建置一個 Prism 的 Xamarin.Forms 專案
  2. 在方案中啟動 NuGet 安裝工具,搜尋套件 ZXing.Net.Mobile.Forms,將這個套件安裝到所有的專案內。
  3. 建置一個 Prism 的 NavigationPage,名稱為 NaviPage
  4. 修改 App.xaml.cs,需要使用導航頁面進入到 MainPage 頁面
            NavigationService.NavigateAsync("Navi/MainPage?title=Hello%20from%20Xamarin.Forms");
  1. 修改 MainPage.xaml,增加一個按鈕與其點擊事件,修改後的 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"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="XFScan.Views.MainPage"
             Title="MainPage">
  <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
    <Label Text="{Binding Title}" />
        <Button Text="Scan" Clicked="Button_Clicked" />
    </StackLayout>
</ContentPage>
  1. 修改 MainPage.xaml 的 Code Behind,增加按鈕事件的定義,程式碼如下:
    在 Code Behind 中,產生一個 ZXingScannerPage 物件,並且綁定其 OnScanResult 事件,其會當有掃描結果的時候,會來執行這個事件委派方法,在該處理方法中,使用 IsScanning 設定為 false,停止掃描動作,接著將結果顯示出來。
using Xamarin.Forms;
using ZXing.Net.Mobile.Forms;

namespace XFScan.Views
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, System.EventArgs e)
        {
            // 產生掃描條碼頁面物件
            var scanPage = new ZXingScannerPage();
            scanPage.Title = "請掃描條碼";

            scanPage.OnScanResult += (result) => {
                // 停止掃描
                scanPage.IsScanning = false;

                // 顯示掃描結果
                Device.BeginInvokeOnMainThread(() => {
                    Navigation.PopAsync();
                    DisplayAlert("Scanned Barcode", result.Text, "OK");
                });
            };

            // 導航到掃描條碼頁面
            await Navigation.PushAsync(scanPage);
        }
    }
}

Android 專案修正

  1. 找到 MainActivity.cs 檔案,修正 MainActivity 類別如下:
    在 OnCreate 方法內,需要呼叫ZXing.Net.Mobile.Forms.Android.Platform.Init();`,以便進行進行 ZXing 元件初始化動作。
    另外,需要增加 OnRequestPermissionsResult 方法定義。
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.tabs;
            ToolbarResource = Resource.Layout.toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            // 在此進行 ZXing 元件初始化
            ZXing.Net.Mobile.Forms.Android.Platform.Init();

            LoadApplication(new App(new AndroidInitializer()));
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
  1. 執行這個 Android 專案,當進入到首頁頁面,點選 Scan 按鈕,就可以看到如下圖的掃描畫面。
    QRCode掃描
  2. 下圖是有掃描到發票 QR Code 的結果畫面
    QRCode掃描結果

參考資料

範例專案