建立效果
效果會簡化控制項的自訂。 本文示範如何在控制項取得焦點時,建立變更 Entry 控制項背景色彩的效果。
在每個平台特定專案中建立效果的程序如下:
- 建立
PlatformEffect
類別的子類別。 - 覆寫
OnAttached
方法,並撰寫自訂控制項的邏輯。 - 覆寫
OnDetached
方法,並撰寫清除控制項自訂的邏輯 (如有必要)。 - 將
ResolutionGroupName
屬性新增至效果類別。 這個屬性會設定效果的全公司命名空間,防止與其他同名效果發生衝突。 請注意,每個專案只能套用一次這個屬性。 - 將
ExportEffect
屬性新增至效果類別。 這個屬性會使用 的唯一標識符 Xamarin.Forms來註冊效果,以及組名,以在將效果套用至控件之前找出效果。 屬性會採用兩個參數 – 效果的類型名稱,以及用來找出效果再將它套用至控制項的唯一字串。
然後就可以將效果附加至適當控制項來使用效果。
注意
您可以選擇每個平台專案是否提供效果。 嘗試在未註冊的情況下使用效果,會傳回不執行任何動作的非 Null 值。
範例應用程式示範 FocusEffect
,在控制項獲得焦點時變更控制項的背景色彩。 下圖說明應用程式範例中每個專案的責任,以及這些專案之間的關聯性:
HomePage
上的 Entry
控制項是由每個平台特定專案中的 FocusEffect
類別自訂。 每個 FocusEffect
類別都衍生自每個平台的 PlatformEffect
類別。 這會導致以平台特定背景色彩轉譯 Entry
控制項,在控制項取得焦點時變更,如下列螢幕擷取畫面所示:
在每個平台上建立效果
下列各節會討論 FocusEffect
類別的平台特定實作。
iOS 專案
下列程式碼範例會示範 iOS 專案的 FocusEffect
實作:
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(EffectsDemo.iOS.FocusEffect), nameof(EffectsDemo.iOS.FocusEffect))]
namespace EffectsDemo.iOS
{
public class FocusEffect : PlatformEffect
{
UIColor backgroundColor;
protected override void OnAttached ()
{
try {
Control.BackgroundColor = backgroundColor = UIColor.FromRGB (204, 153, 255);
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
protected override void OnElementPropertyChanged (PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged (args);
try {
if (args.PropertyName == "IsFocused") {
if (Control.BackgroundColor == backgroundColor) {
Control.BackgroundColor = UIColor.White;
} else {
Control.BackgroundColor = backgroundColor;
}
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
OnAttached
方法會使用 UIColor.FromRGB
方法將控制項的 BackgroundColor
屬性設為淺紫色,並將這個色彩也儲存在欄位中。 這項功能會包裝在 try
/catch
區塊中,以免效果附加至的控制項沒有 BackgroundColor
屬性。 因為沒有必要的清除,所以 OnDetached
方法不提供實作。
覆 OnElementPropertyChanged
寫會回應 控件上的 Xamarin.Forms 可系結屬性變更。 當 IsFocused
屬性變更時,如果控制項有焦點,則控制項的 BackgroundColor
屬性會變更為白色,否則會變更為淺紫色。 這項功能會包裝在 try
/catch
區塊中,以免效果附加至的控制項沒有 BackgroundColor
屬性。
Android 專案
下列程式碼範例會示範 Android 專案的 FocusEffect
實作:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.Droid.FocusEffect), nameof(EffectsDemo.Droid.FocusEffect))]
namespace EffectsDemo.Droid
{
public class FocusEffect : PlatformEffect
{
Android.Graphics.Color originalBackgroundColor = new Android.Graphics.Color(0, 0, 0, 0);
Android.Graphics.Color backgroundColor;
protected override void OnAttached()
{
try
{
backgroundColor = Android.Graphics.Color.LightGreen;
Control.SetBackgroundColor(backgroundColor);
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
try
{
if (args.PropertyName == "IsFocused")
{
if (((Android.Graphics.Drawables.ColorDrawable)Control.Background).Color == backgroundColor)
{
Control.SetBackgroundColor(originalBackgroundColor);
}
else
{
Control.SetBackgroundColor(backgroundColor);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
OnAttached
方法呼叫 SetBackgroundColor
方法將控制項的背景色彩設定為淺綠色,並將這個色彩也儲存在欄位中。 這項功能會包裝在 try
/catch
區塊中,以免效果附加至的控制項沒有 SetBackgroundColor
屬性。 因為沒有必要的清除,所以 OnDetached
方法不提供實作。
覆 OnElementPropertyChanged
寫會回應 控件上的 Xamarin.Forms 可系結屬性變更。 當 IsFocused
屬性變更時,如果控制項有焦點,則控制項的背景色彩會變更為白色,否則會變更為淺綠色。 這項功能會包裝在 try
/catch
區塊中,以免效果附加至的控制項沒有 BackgroundColor
屬性。
通用 Windows 平台專案
下列程式碼範例示範通用 Windows 平台 (UWP) 專案的 FocusEffect
實作:
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.UWP.FocusEffect), nameof(EffectsDemo.UWP.FocusEffect))]
namespace EffectsDemo.UWP
{
public class FocusEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
(Control as Windows.UI.Xaml.Controls.Control).Background = new SolidColorBrush(Colors.Cyan);
(Control as FormsTextBox).BackgroundFocusBrush = new SolidColorBrush(Colors.White);
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}
}
OnAttached
方法會將控制項的 Background
屬性設成青色,並將 BackgroundFocusBrush
屬性設為白色。 這項功能會包裝在 try
/catch
區塊中,以免效果附加至的控制項缺少這些屬性。 因為沒有必要的清除,所以 OnDetached
方法不提供實作。
使用效果
從 Xamarin.Forms .NET Standard 連結庫或共享連結庫專案取用效果的程式如下:
- 宣告效果將要使用的控制項。
- 藉由將效果新增至控制項的
Effects
集合,來將效果附加至控制項。
注意
效果執行個體只能附加至單一控制項。 因此,效果必須解析兩次,才能用於兩個控制項。
在 XAML 中使用效果
下列 XAML 程式碼範例示範 FocusEffect
附加至的 Entry
控制項:
<Entry Text="Effect attached to an Entry" ...>
<Entry.Effects>
<local:FocusEffect />
</Entry.Effects>
...
</Entry>
.NET Standard 程式庫中的 FocusEffect
類別支援在 XAML 中使用效果,如下列程式碼範例所示:
public class FocusEffect : RoutingEffect
{
public FocusEffect () : base ($"MyCompany.{nameof(FocusEffect)}")
{
}
}
FocusEffect
類別子類別化 RoutingEffect
類別,其代表包裝內部效果的平台獨立效果通常是平台特定效果。 FocusEffect
類別會呼叫基底類別建構函式,傳入解析群組名稱串連構成的參數 (使用效果類別上的 ResolutionGroupName
屬性指定),和使用效果類別上的 ExportEffect
屬性指定的唯一識別碼。 因此,當 Entry
在執行階段初始化後,MyCompany.FocusEffect
的新執行個體就會新增至控制項的 Effects
集合。
使用行為或使用附加屬性,也可以將效果附加至控制項。 如需使用行為將效果附加至控制項的詳細資訊,請參閱可重複使用的 EffectBehavior。 如需使用附加屬性將效果附加至控制項的詳細資訊,請參閱將參數傳遞至效果。
在 C 中使用效果#
下列程式碼範例顯示 C# 中的對等 Entry
:
var entry = new Entry {
Text = "Effect attached to an Entry",
...
};
藉由將效果新增至控制項的 Effects
集合,來將 FocusEffect
附加至 Entry
執行個體,如下列程式碼範例所示:
public HomePageCS ()
{
...
entry.Effects.Add (Effect.Resolve ($"MyCompany.{nameof(FocusEffect)}"));
...
}
Effect.Resolve
傳回指定名稱的 Effect
,它是解析群組名稱的串連 (使用效果類別上的 ResolutionGroupName
屬性指定),和使用效果類別上的 ExportEffect
屬性指定的唯一識別碼。 如果某個平台不提供效果,則 Effect.Resolve
方法會傳回非 null
值。
摘要
本文示範如何在控制項取得焦點時,建立變更 Entry
控制項背景色彩的效果。