Xamarin.Forms 基础——Behavior——EventToCommandBehavior

可重用的EventToCommandBehavior

事件触发时调用命令

PDF用于离线使用
示例代码:
相关API:

让我们知道你对此的感受

最后更新:2016年4月

行为可用于将命令与未设计为与命令交互的控件相关联。本文演示如何在事件触发时使用Xamarin.Forms行为来调用命令。

概观

EventToCommandBehavior班是响应执行命令,可重复使用的Xamarin.Forms定制行为的任何事件触发。默认情况下,该事件的事件参数将被传递给该命令,并且可以由一个IValueConverter实现来选择转换。

为了使用该行为,必须设置以下行为属性:

  • EventName - 行为侦听的事件的名称。
  • 命令 - 要执行的ICommand。该行为期望在附加的控件ICommand上找到BindingContext可以从父元素继承的实例。

还可以设置以下可选行为属性:

  • CommandParameter - object将传递给命令的命令。
  • 转换器 - 一种IValueConverter实现,它将通过绑定引擎在目标之间传递时更改事件参数数据的格式。

创建行为

这个EventToCommandBehavior课程来自BehaviorBase<T>班级,这又从Behavior<T>课堂上得出。BehaviorBase<T>该类的目的是为需要BindingContext将该行为设置为附加控件的任何Xamarin.Forms行为提供基类。这样可以确保在行为消耗时,该行为可以绑定到ICommandCommand属性并执行该属性。

BehaviorBase<T>类提供一个可重写的OnAttachedTo,其设定方法BindingContext的行为和可重写的OnDetachingFrom该清理方法BindingContext。此外,该类存储对AssociatedObject属性中附加控件的引用。

实施可绑定属性

为了在事件触发时执行用户定义的命令,EventToCommandBehavior该类定义了四个BindableProperty实例,如以下代码示例所示:

public class EventToCommandBehavior : BehaviorBase<View>
{
  public static readonly BindableProperty EventNameProperty =
    BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
  public static readonly BindableProperty CommandProperty =
    BindableProperty.Create ("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
  public static readonly BindableProperty CommandParameterProperty =
    BindableProperty.Create ("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
  public static readonly BindableProperty InputConverterProperty =
    BindableProperty.Create ("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);

  public string EventName { ... }
  public ICommand Command { ... }
  public object CommandParameter { ... }
  public IValueConverter Converter { ...  }
  ...
}

EventToCommandBehavior类被使用时,Command属性应该是数据绑定到一个ICommand被执行以响应在EventName属性中定义的事件触发。该行为会期望找到ICommandBindingContext所连接的控制的。

默认情况下,事件的事件参数将传递给该命令。该数据可以通过绑定引擎在目标之间传递,可以通过将IValueConverter实现指定为Converter属性值来进行转换。或者,可以通过指定CommandParameter属性值将参数传递给命令。

实现覆盖

EventToCommandBehavior类重写OnAttachedToOnDetachingFrom所述的方法BehaviorBase<T>类,如在下面的代码例如:

public class EventToCommandBehavior : BehaviorBase<View>
{
  ...
  protected override void OnAttachedTo (View bindable)
  {
    base.OnAttachedTo (bindable);
    RegisterEvent (EventName);
  }

  protected override void OnDetachingFrom (View bindable)
  {
    DeregisterEvent (EventName);
    base.OnDetachingFrom (bindable);
  }
  ...
}

OnAttachedTo方法通过调用该方法执行设置RegisterEvent,将该EventName属性的值作为参数传递。该OnDetachingFrom方法通过调用该方法执行清理DeregisterEvent,将该EventName属性的值作为参数传递。

实施行为功能

该行为的目的是执行由Command属性定义的命令以响应由属性定义的事件触发EventName。核心行为功能如下代码示例所示:

public class EventToCommandBehavior : BehaviorBase<View>
{
  ...
  void RegisterEvent (string name)
  {
    if (string.IsNullOrWhiteSpace (name)) {
      return;
    }

    EventInfo eventInfo = AssociatedObject.GetType ().GetRuntimeEvent (name);
    if (eventInfo == null) {
      throw new ArgumentException (string.Format ("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
    }
    MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo ().GetDeclaredMethod ("OnEvent");
    eventHandler = methodInfo.CreateDelegate (eventInfo.EventHandlerType, this);
    eventInfo.AddEventHandler (AssociatedObject, eventHandler);
  }

  void OnEvent (object sender, object eventArgs)
  {
    if (Command == null) {
      return;
    }

    object resolvedParameter;
    if (CommandParameter != null) {
      resolvedParameter = CommandParameter;
    } else if (Converter != null) {
      resolvedParameter = Converter.Convert (eventArgs, typeof(object), null, null);
    } else {
      resolvedParameter = eventArgs;
    }       

    if (Command.CanExecute (resolvedParameter)) {
      Command.Execute (resolvedParameter);
    }
  }
  ...
}

RegisterEvent方法是响应于EventToCommandBehavior附加到控件而执行的,它接收EventName属性的值作为参数。该方法然后尝试EventName在附带的控件上定位属性中定义的事件。只要可以找到事件,该OnEvent方法就被注册为事件的处理程序方法。

OnEvent方法是在EventName属性中定义的事件触发时执行的。只要该Command属性引用了一个有效ICommand的方法,该方法会尝试检索一个参数传递给ICommand如下:

  • 如果CommandParameter属性定义了一个参数,则它将被检索。
  • 否则,如果Converter属性定义了一个IValueConverter实现,则转换器被执行,并且通过绑定引擎在事件目标之间传递的事件参数数据进行转换。
  • 否则,假定事件参数为参数。

ICommand然后执行数据绑定,将参数传递给命令,前提是该CanExecute方法返回true

虽然这里未示出,但是EventToCommandBehavior还包括DeregisterEvent通过该OnDetachingFrom方法执行的方法。该DeregisterEvent方法用于定位和注销EventName属性中定义的事件,以便清除任何潜在的内存泄漏。

消费行为

EventToCommandBehavior类可以被附连到Behaviors一个控制集合,如下面的XAML代码示例表明:

<ListView ItemsSource="{Binding People}">
  <ListView.Behaviors>
    <local:EventToCommandBehavior EventName="ItemSelected" Command="{Binding OutputAgeCommand}"
                                  Converter="{StaticResource SelectedItemConverter}" />
  </ListView.Behaviors>
</ListView>
<Label Text="{Binding SelectedItemText}" />

等效的C#代码显示在以下代码示例中:

var listView = new ListView ();
listView.SetBinding (ItemsView<Cell>.ItemsSourceProperty, "People");
listView.Behaviors.Add (new EventToCommandBehavior {
  EventName = "ItemSelected",
  Command = ((HomePageViewModel)BindingContext).OutputAgeCommand,
  Converter = new SelectedItemEventArgsToSelectedItemConverter ()
});

var selectedItemLabel = new Label ();
selectedItemLabel.SetBinding (Label.TextProperty, "SelectedItemText");

Command行为的属性是绑定到数据OutputAgeCommand相关联的视图模型的属性,而Converter属性被设置为SelectedItemConverter实例,它返回SelectedItemListView来自SelectedItemChangedEventArgs

在运行时,行为将响应与控件的交互。当选择项目时ListViewItemSelected事件将触发,这将OutputAgeCommand在ViewModel中执行。反过来,这将更新绑定到的ViewModel SelectedItemText属性Label,如以下屏幕截图所示:

使用此行为在事件触发时执行命令的优点是,命令可以与未设计为与命令交互的控件相关联。此外,这将从代码隐藏文件中删除锅炉板事件处理代码。

概要

本文演示了使用Xamarin.Forms行为在事件触发时调用命令。行为可用于将命令与未设计为与命令交互的控件相关联。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值