Xamarin.Forms行为
将功能添加到控件中,无需进行子类化
-
PDF用于离线使用
- 示例代码:
- 相关API:
让我们知道你对此的感受
最后更新:2016年4月
Xamarin.Forms行为是通过从Behavior或Behavior <T>类派生而创建的。本文演示如何创建和使用Xamarin.Forms行为。
概观
创建Xamarin.Forms行为的过程如下:
- 创建一个继承自
Behavior
或Behavior<T>
类的类,T
应该在哪个行为应用的控件的类型在哪里。 - 覆盖
OnAttachedTo
执行任何所需设置的方法。 - 覆盖该
OnDetachingFrom
方法以执行任何所需的清理。 - 实现行为的核心功能。
这导致以下代码示例中显示的结构:
public class CustomBehavior : Behavior<View>
{
protected override void OnAttachedTo (View bindable)
{
base.OnAttachedTo (bindable);
// Perform setup
}
protected override void OnDetachingFrom (View bindable)
{
base.OnDetachingFrom (bindable);
// Perform clean up
}
// Behavior implementation
}
该OnAttachedTo
方法在行为附加到控件后立即被触发。此方法接收对其附加的控件的引用,并可用于注册事件处理程序或执行支持行为功能所需的其他设置。例如,您可以订阅控件上的事件。然后,行为功能将在事件的事件处理程序中实现。
OnDetachingFrom
当从控件中删除行为时,该方法被触发。此方法接收对其附加的控件的引用,并用于执行任何所需的清理。例如,您可以取消订阅控件上的事件,以防止内存泄漏。
然后可以通过将行为附加到Behaviors
相应控件的集合来消除行为。
创建Xamarin.Forms行为
示例应用程序演示了一个NumericValidationBehavior
,它突出显示用户输入Entry
红色控件的值(如果不是)double
。行为如下代码示例所示:
public class NumericValidationBehavior : Behavior<Entry>
{
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += OnEntryTextChanged;
base.OnAttachedTo(entry);
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= OnEntryTextChanged;
base.OnDetachingFrom(entry);
}
void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
double result;
bool isValid = double.TryParse (args.NewTextValue, out result);
((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
}
}
在NumericValidationBehavior
从导出Behavior<T>
类,这里T
是一个Entry
。该OnAttachedTo
方法注册事件的事件处理程序TextChanged
,OnDetachingFrom
方法取消注册TextChanged
事件,以防止内存泄漏。行为的核心功能是通过OnEntryTextChanged
方法来提供的,该方法将用户输入的值解析为Entry
,TextColor
如果值不是,将属性设置为红色double
。
Xamarin.Forms没有设置BindingContext
一个行为,因为行为可以通过样式共享并应用于多个控件。
消耗Xamarin.Forms行为
每个Xamarin.Forms控件都有一个Behaviors
集合,可以添加一个或多个行为,如以下XAML代码示例所示:
<Entry Placeholder="Enter a System.Double">
<Entry.Behaviors>
<local:NumericValidationBehavior />
</Entry.Behaviors>
</Entry>
Entry
C#中的等效项显示在以下代码示例中:
var entry = new Entry { Placeholder = "Enter a System.Double" };
entry.Behaviors.Add (new NumericValidationBehavior ());
根据行为实现,运行时行为将响应与控件的交互。以下屏幕截图演示了响应无效输入的行为:
针对特定控件类型(或可应用于许多控件的超类)编写行为,并且只应将其添加到兼容控件中。尝试将行为附加到不兼容的控件将导致抛出异常。
消费Xamarin.Forms行为与风格
行为也可以被显式或隐式风格所消耗。但是,创建一个设置Behaviors
控件属性的样式是不可能的,因为属性是只读的。解决方案是将附加的属性添加到控制添加和删除行为的行为类。过程如下:
- 将一个附加的属性添加到行为类中,该类将用于控制行为附加到的控件的添加或删除行为。确保附加的属性注册一个
propertyChanged
将在属性值更改时执行的委托。 static
为附加属性创建一个getter和setter。- 在
propertyChanged
代理中实现逻辑来添加和删除行为。
以下代码示例显示了附加属性,用于控制添加和删除NumericValidationBehavior
:
public class NumericValidationBehavior : Behavior<Entry>
{
public static readonly BindableProperty AttachBehaviorProperty =
BindableProperty.CreateAttached ("AttachBehavior", typeof(bool), typeof(NumericValidationBehavior), false, propertyChanged: OnAttachBehaviorChanged);
public static bool GetAttachBehavior (BindableObject view)
{
return (bool)view.GetValue (AttachBehaviorProperty);
}
public static void SetAttachBehavior (BindableObject view, bool value)
{
view.SetValue (AttachBehaviorProperty, value);
}
static void OnAttachBehaviorChanged (BindableObject view, object oldValue, object newValue)
{
var entry = view as Entry;
if (entry == null) {
return;
}
bool attachBehavior = (bool)newValue;
if (attachBehavior) {
entry.Behaviors.Add (new NumericValidationBehavior ());
} else {
var toRemove = entry.Behaviors.FirstOrDefault (b => b is NumericValidationBehavior);
if (toRemove != null) {
entry.Behaviors.Remove (toRemove);
}
}
}
...
}
的NumericValidationBehavior
类包含一个名为附加属性AttachBehavior
与static
获取和设置,其控制增加或移除的行为的给其将要连接的控制。此附加属性注册OnAttachBehaviorChanged
将在属性的值更改时执行的方法。此方法基于AttachBehavior
附加属性的值将该行为添加或删除到控件。
以下代码示例显示了使用附加属性的显式样式,并可应用于控件:NumericValidationBehavior
AttachBehavior
Entry
<Style x:Key="NumericValidationStyle" TargetType="Entry">
<Style.Setters>
<Setter Property="local:NumericValidationBehavior.AttachBehavior" Value="true" />
</Style.Setters>
</Style>
的Style
可被应用到Entry
通过其设置控制Style
属性的Style
使用实例StaticResource
标记扩展,如在下面的代码示例表明:
<Entry Placeholder="Enter a System.Double" Style="{StaticResource NumericValidationStyle}">
有关样式的更多信息,请参阅样式。
虽然您可以将绑定属性添加到在XAML中设置或查询的行为,但如果创建具有状态的行为,则不应在a Style
中的控件之间共享ResourceDictionary
。
从控件中删除一个行为
OnDetachingFrom
当从控件中删除某个行为时,将触发该方法,并且用于执行任何所需的清除,例如从事件中取消订阅以防止内存泄漏。但是,除非控件的Behaviors
集合由Remove
或Clear
方法修改,否则行为不会从控件中隐式删除。以下代码示例演示如何从控件的Behaviors
集合中删除特定行为:
var toRemove = entry.Behaviors.FirstOrDefault (b => b is NumericValidationBehavior);
if (toRemove != null) {
entry.Behaviors.Remove (toRemove);
}
或者,Behaviors
可以清除控件的集合,如以下代码示例所示:
entry.Behaviors.Clear();
此外,请注意,当从导航堆栈中弹出页面时,行为不会从控件中隐式删除。相反,在页面超出范围之前,必须明确删除它们。
概要
本文演示了如何创建和使用Xamarin.Forms行为。Xamarin.Forms行为是通过派生自Behavior
或Behavior<T>
类创建的。