使用样式属性设置输入行为

问题描述

我已经这样定义了自己的风格:

<ContentView.Resources>
    <ResourceDictionary>
        <Style targettype="Entry" x:Key="IntegralEntryBehavior">
            <Setter Property="Behaviors" Value="valid:EntryIntegerValidationBehavior"/>
        </Style>
    </ResourceDictionary>
</ContentView.Resources>

以及多个类似的条目:

<StackLayout Grid.Column="0" Grid.Row="0">
    <Entry Style="{StaticResource IntegralEntryBehavior}"/>
</StackLayout>

如果我这样定义Entry行为,则会得到一个错误Entry.Behaviors property is readonly,但是无需在Entry内部使用Style属性就可以定义行为,例如:

<Entry.Behaviors>
    <valid:EntryIntegerValidationBehavior/>
</Entry.Behaviors>

这些方法之间有什么区别?为什么只有第二种方法有效?是否可以修改第一种方法以使其起作用?与第二个选项相比,我正在寻找一种为每个条目定义此行为的较短方法

解决方法

您可以在此处签出示例:

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/behaviors/creating#consuming-a-xamarinforms-behavior-with-a-style

基本上,将附加属性添加到您的行为,然后将样式设置器的属性设置为该附加属性。附加属性可以将自身添加到您将其附加到的Entry

public class EntryIntegerValidationBehavior : Behavior<Entry>
{
  public static readonly BindableProperty AttachBehaviorProperty =
    BindableProperty.CreateAttached ("AttachBehavior",typeof(bool),typeof(EntryIntegerValidationBehavior),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 EntryIntegerValidationBehavior ());
    } else {
        var toRemove = entry.Behaviors.FirstOrDefault (b => b is EntryIntegerValidationBehavior);
        if (toRemove != null) {
            entry.Behaviors.Remove (toRemove);
        }
    }
  }

  // Actual behavior code here

}

最后编辑您的样式,如下所示:

    <Style TargetType="Entry" x:Key="IntegralEntryBehavior">
        <Setter Property="valid:EntryIntegerValidationBehavior.AttachBehavior" Value="true"/>
    </Style>