3

axmlとViewModelの間、またはFocusChangedなどのようなものの間で「タッチ」コマンドバインディングを行う方法を探しています.

単純な「クリック」コマンドは次のようにうまく機能します: local:MvxBind="{'Touch':{'Path':'CameraButtonCommand'}}" />

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

ただし、コントロールの他のイベント タイプ (この場合は ImageButton) を試しましたが、それらは処理されていません。View Class のイベント リストを確認すると、次のように表示されます。

    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 があり、それが機能しない理由であるかどうか疑問に思っています。

また、FindViewById メソッドによって適切なコントロールを取得する View クラスのこれらのイベントにメソッドをアタッチしようとしましたが、今回は期待どおりに動作します。しかし、どういうわけか、コマンドを使用して axml でそれを行うことはできません。

また、もう一つ。「クリック」イベントは、「EventArgs」オブジェクトをパラメーターの 1 つとして送信し、オブジェクト参照も送信します。View Class でこの動作を行うと簡単にわかりますが、バインドでこれを行うと、ViewModel で Command を処理しているときにこれらの引数が表示されません。

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 に答える