Xamarin.Forms 附加行為 Behaviors 應用
在這份範例中,將會記錄如何自行客製化一個行為 (Behavior),用來減少在進行開發專案過程之中,不再需要過度撰寫許多程式碼;當需要某些功能或特性的時候,可以直接在 XAML 上進行宣告即可,如此,在頁面上的檢視(View 也可以稱為控制項 Control),就具備了這些預先設定的行為特性。
在這個範例專案中,將會設計一個使用者登入系統的頁面,這個頁面內有一個
Label
與兩個 Entry
控制項,您想要設計這樣的行為:當使用者尚未輸入任何帳號與密碼的時候,Entry
控制項的背景要顯示紅色,提醒使用者要輸入文字到這些欄位中;若使用者有在 Entry
輸入了文字,但是不足 6 個字元,則會使用紅色文字顏色作為提醒。因此,您將會需要新增一個新圍,提供這兩個功能,並且在 XAML 語言上直接套用新設計的行為。
底下為這個範例專案的執行結果
這份筆記中的專案,可以參考 https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFAttBehavior
產生一個附加行為 Behavior
- 產生一個類別檔案
- 在這個類別檔案內,以底下程式碼加以置換
- 在這個類別檔案內,透過
BindableProperty.CreateAttached
宣告與產生的附加屬性,這個BindableProperty
必須要宣告為靜態。其中,最後一個參數是propertyChanged
是用來處理當這個附加屬性的值有變動的時候,需要呼叫的委派方法。 - 接著,您需要定義兩個方法,用來存取這個附加屬性
GetAttachBehavior
/SetAttachBehavior
- 透過在建立附加屬性物件(
BindableProperty.CreateAttached
)的時候,有指定propertyChanged
參數,您需要定義這個委派方法。OnAttachBehaviorChanged
這個委派方法中,首先會先判斷現在的檢視(View)是不是一個Entry
類型物件,若不是,則不做任何處理。接著會取得新設定的附加屬性值,若該附加屬性的值為真,則會綁定Entry.TextChanged
這個事件,否則,將會解除綁定事件。 - 最後,定義當發生了
TextChanged
事件之後,就會來檢查當時的Entry
控制項的Text
屬性是否有值,若沒有,則會設定背景顏色為紅色;若Text
屬性有值,則會再檢查其輸入的字串長度是否有大於等於六個字元,若沒有,則會設定TextColor
的屬性值為紅色。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XFAttBehavior
{
public class EmptyHighlightBehavior
{
// 產生一個附加屬性,用來定義是否要啟用空字串檢查與提示行為
public static readonly BindableProperty EmptyHighlightProperty =
BindableProperty.CreateAttached(
"EmptyHighlight",
typeof(bool),
typeof(EmptyHighlightBehavior),
false,
propertyChanged: OnAttachBehaviorChanged);
public static bool GetAttachBehavior(BindableObject view)
{
return (bool)view.GetValue(EmptyHighlightProperty);
}
public static void SetAttachBehavior(BindableObject view, bool value)
{
view.SetValue(EmptyHighlightProperty, value);
}
static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
{
var entry = view as Entry;
// 若這個檢視不是 Entry 類別,則不需要做任何處理動作
if (entry == null)
{
return;
}
bool attachBehavior = (bool)newValue;
if (attachBehavior)
{
RefreshBackgroundColor(entry);
entry.TextChanged += OnEntryTextChanged;
}
else
{
entry.TextChanged -= OnEntryTextChanged;
}
}
static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
RefreshBackgroundColor(sender);
}
// 根據現在 Entry 檢視的 Text 屬性值,判斷是否要提示背景顏色,告知該欄位尚未輸入任何值
static void RefreshBackgroundColor(object sender)
{
if (string.IsNullOrEmpty(((Entry)sender).Text))
{
((Entry)sender).BackgroundColor = Color.Red;
}
else
{
if (((Entry)sender).Text.Length >= 6)
{
((Entry)sender).BackgroundColor = Color.Default;
((Entry)sender).TextColor = Color.Default;
}
else
{
((Entry)sender).BackgroundColor = Color.Default;
((Entry)sender).TextColor = Color.Red;
}
}
}
}
}
在 XAML 上使用剛剛定一個行為
- 請打開 MainPage.xaml,如同底下內容。
- 在底下的 XAML 標記語言中,您可以看到有在
Entry
控制項中,使用了附加屬性local:EmptyHighlightBehavior.EmptyHighlight="true"
宣告要使用EmptyHighlightBehavior
這個附加屬性行為功能。
<?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:XFAttBehavior"
x:Class="XFAttBehavior.MainPage">
<ContentPage.Padding>40</ContentPage.Padding>
<StackLayout>
<Label
Text="請登入系統"
VerticalOptions="Center" HorizontalOptions="Center" />
<Entry
Placeholder="請輸入帳號"
local:EmptyHighlightBehavior.EmptyHighlight="true"
/>
<Entry
Placeholder="請輸入密碼"
IsPassword="True"
local:EmptyHighlightBehavior.EmptyHighlight="true"
/>
</StackLayout>
</ContentPage>