关于mvvm:android中的mvvmcross触摸命令绑定

mvvmcross touch command binding in android

我正在寻找一种在axml和ViewModel或诸如FocusChanged等其他东西之间进行"触摸"命令绑定的方法。

一个简单的" Click"命令可以像这样正常工作:
local:MvxBind =" {'Touch':{'Path':'CameraButtonCommand'}}"" />

1
2
3
4
5
6
7
8
9
10
11
12
    public IMvxCommand CameraButtonCommand
    {
        get
        {
            return new MvxRelayCommand(
                () =>
                {
                    RequestNavigate<AugRealityViewModel>(true);
                })
            ;
        }
    }

但是,我尝试了controll的其他事件类型(在本例中为ImageButton),并且未对其进行处理。在查看类中查看事件列表后,我看到了以下内容:

1
2
3
4
5
    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方法获得适当的控制,这次它可以按预期工作。但是以某种方式我无法通过Commands在axml中做到这一点。

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


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

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

例如,要绑定:

1
public event EventHandler<View.LongClickEventArgs> LongClick;

您可以添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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; }
    }
}

可以使用以下命令在安装程序中进行配置:

1
2
3
4
5
6
    protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
    {
        base.FillTargetFactories(registry);

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

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

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