共用方式為


建立效果

效果會簡化控制項的自訂。 本文示範如何在控制項取得焦點時,建立變更 Entry 控制項背景色彩的效果。

在每個平台特定專案中建立效果的程序如下:

  1. 建立 PlatformEffect 類別的子類別。
  2. 覆寫 OnAttached 方法,並撰寫自訂控制項的邏輯。
  3. 覆寫 OnDetached 方法,並撰寫清除控制項自訂的邏輯 (如有必要)。
  4. ResolutionGroupName 屬性新增至效果類別。 這個屬性會設定效果的全公司命名空間,防止與其他同名效果發生衝突。 請注意,每個專案只能套用一次這個屬性。
  5. 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 連結庫或共享連結庫專案取用效果的程式如下:

  1. 宣告效果將要使用的控制項。
  2. 藉由將效果新增至控制項的 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 控制項背景色彩的效果。