第二十三章:触发器和行为(七)

行为

触发器和行为通常是串联讨论的,因为它们具有一些应用重叠。 有时候你会感到困惑是否使用触发器或行为,因为似乎要么这样做
工作。
你可以用触发器做任何事情,你也可以做一个行为。 但是,行为总是涉及一些代码,这是一个派生自Behavior 的类。 如果您正在为EventTrigger编写Action 派生词,或者为其他触发器的EnterActions或ExitActions集合编写,则触发器仅涉及代码。
显然,如果您可以使用其中一个触发器执行所需操作而无需编写任何代码,则不要使用行为。 但有时它并不那么清楚。
让我们比较执行相同工作的触发器和行为。
本章前面显示的TriggerEntryValidation程序使用一个名为NumericEntryAction的类,它检查输入到Entry视图中的数字是否有资格作为有效的double值,如果不是,则将文本设置为红色:

namespace Xamarin.FormsBook.Toolkit
{ 
    public class NumericValidationAction : TriggerAction<Entry> 
    {
        protected override void Invoke(Entry entry)
        {
            double result;
            bool isValid = Double.TryParse(entry.Text, out result);
            entry.TextColor = isValid ? Color.Default : Color.Red;
        }
    }
}

这是在附加到条目的EventTrigger中引用的:

<Entry Placeholder="Enter a System.Double">
    <Entry.Triggers>
        <EventTrigger Event="TextChanged">
            <toolkit:NumericValidationAction />
        </EventTrigger>
    </Entry.Triggers>
</Entry>

您可以对同一作业使用行为。 第一步是从Behavior 派生一个类。 泛型参数是行为可以处理的最通用的基类。 在这个例子中,这是一个Entry视图。 然后,重写两个名为OnAttachedTo和OnDetachingFrom的虚拟方法。 当行为附加到特定可视对象时,将调用OnAttachedTo方法,并为您的行为提供初始化自身的机会。 通常这涉及将一些事件处理程序附加到对象。 从可视对象中删除行为时,将调用OnDetachingFrom方法。 即使仅在程序终止时发生这种情况,您也应该撤消OnAttachedTo方法所做的任何事情。
这是NumericValidationBehavior类:

namespace Xamarin.FormsBook.Toolkit
{
    public class NumericValidationBehavior : Behavior<Entry>
    {
        protected override void OnAttachedTo(Entry entry)
        {
            base.OnAttachedTo(entry);
            entry.TextChanged += OnEntryTextChanged;
        }
 
        protected override void OnDetachingFrom(Entry entry)
        {
            base.OnDetachingFrom(entry);
            entry.TextChanged -= OnEntryTextChanged;
        }
        void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            double result;
            bool isValid = Double.TryParse(args.NewTextValue, out result);
            ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
        }
    }
}

OnAttachedTo方法为Entry的TextChanged事件附加处理程序,OnDetachingFrom方法分离该处理程序。 处理程序本身与NumericValidationAction中的Invoke方法执行相同的工作。
因为NumericValidationBehavior类安装TextChanged事件的处理程序,所以可以使用该行为而不指定类名以外的任何内容。 这是BehaviorEntryValidation程序的XAML文件,它与使用EventTrigger的早期程序不同,它通过指定应用于四个Entry视图的隐式样式的行为:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit=
                 "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
             x:Class="BehaviorEntryValidation.BehaviorEntryValidationPage"
             Padding="50">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Entry">
                <Style.Behaviors>
                    <toolkit:NumericValidationBehavior />
                </Style.Behaviors>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <Entry Placeholder="Enter a System.Double" />
        <Entry Placeholder="Enter a System.Double" />
        <Entry Placeholder="Enter a System.Double" />
        <Entry Placeholder="Enter a System.Double" />
    </StackLayout>
</ContentPage>

此Style对象在四个Entry视图中共享,因此只实例化一个NumericValidationBehavior对象。 由于此单个对象附加到四个Entry视图中的每一个,因此它会在每个视图上附加一个TextChanged处理程序,以便单个NumericValidationBehavior对象在四个视图上独立运行:
2019_04_05_200913
在这个特定的例子中,TriggerAction比行为更受欢迎,因为它代码较少而代码不引用特定事件,因此它更加通用。
但是行为可以像您想要的那样一般化或特定,行为也可以通过数据绑定更全面地参与XAML文件。

猜你喜欢

转载自yq.aliyun.com/articles/696908