3

我正在寻找一种在 axml 和 ViewModel 之间进行“Touch”命令绑定的方法,或者像 FocusChanged 等其他一些方法。

一个简单的“单击”命令可以正常工作,如下所示:local:MvxBind="{'Touch':{'Path':'CameraButtonCommand'}}" />

    public IMvxCommand CameraButtonCommand
    {
        get
        {
            return new MvxRelayCommand(
                () =>
                {
                    RequestNavigate<AugRealityViewModel>(true);
                })
            ;
        }
    }

但是,我已经为控件尝试了其他事件类型(在本例中是 ImageButton)并且它们没有被处理。当我检查视图类中的事件列表时,我看到了这些:

    public event EventHandler Click;
    public event EventHandler<View.CreateContextMenuEventArgs> ContextMenuCreated;
    public event EventHandler<View.FocusChangeEventArgs> FocusChange;
    public event EventHandler<View.KeyEventArgs> KeyPress;
    public event EventHandler<View.LongClickEventArgs> LongClick;

只有 Click 事件附加了通用的 EventHandler,而其他事件具有通用的 EventHandler,我想知道这是否是它不起作用的原因。

我还尝试将方法附加到 View 类中的这些事件,通过 FindViewById 方法获得适当的控制,这次它按预期工作。但不知何故,我无法通过命令在 axml 中做到这一点。

还有一件事。“Click”事件正在发送“EventArgs”对象作为参数之一,也是对象引用。如果我在 View Class 中执行此行为,我可以轻松地看到这一点,但是当我通过绑定执行此操作时,我在 ViewModel 中处理命令时看不到这些参数。

4

1 回答 1

4

该框架可以自动绑定任何需要 EventHandler 类型的事件。但是,对于任何需要模板化 EventHandler(带有自定义 EventArgs)的事件,那么您是正确的 - 您需要包含自定义绑定。

好消息是自定义绑定很容易编写和包含。

例如,要绑定:

public event EventHandler<View.LongClickEventArgs> LongClick;

您可以包括以下内容:

public class LongPressEventBinding
    : MvxBaseAndroidTargetBinding
{
    private readonly View _view;
    private IMvxCommand _command;

    public LongPressEventBinding(View view)
    {
        _view = view;
        _view.LongClick += ViewOnLongClick;
    }

    private void ViewOnLongClick(object sender, View.LongClickEventArgs eventArgs)
    {
        if (_command != null)
        {
            _command.Execute();
        }
    }

    public override void SetValue(object value)
    {
        _command = (IMvxCommand)value;
    }

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            _view.Click -= ViewOnLongClick;
        }
        base.Dispose(isDisposing);
    }

    public override Type TargetType
    {
        get { return typeof(IMvxCommand); }
    }

    public override MvxBindingMode DefaultMode
    {
        get { return MvxBindingMode.OneWay; }
    }
}

可以使用以下内容在设置中进行配置:

    protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
    {
        base.FillTargetFactories(registry);

        registry.RegisterFactory(new MvxCustomBindingFactory<View>("LongPress", view => new LongPressEventBinding(view)));
    }

请注意,您不能编写绑定到所有不同事件类型的单个类 - 因为编译器要求您为 EventArgs 包含正确的类型。但是,如果您愿意,您可以很容易地更改public class LongClickEventBinding为类似的东西public class CustomEventBinding<TViewType, TEventArgsType>


关于应该将什么参数传递给 IMvxCommand Execute 方法,我想这在一定程度上取决于所讨论的方法,并且还取决于您是否需要 ViewModel 支持多个平台,或者它是否仅适用于 Android。

于 2012-08-06T15:10:02.397 回答