2

MvvmCrossバインディングを使用したコマンドの代わりに、Caliburn.Microと同じように単純なアクションメソッドを使用することは可能ですか?

例:

    public void Action()
    {
        Tip = 11;
    }

<Button
    android:text="Button"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/button1"
    local:MvxBind="Click Action" />

それはそのままでは動作しません、私はそれをテストしました。

新しいターゲットバインディングの追加に関するサンプルはたくさん見つかりましたが、新しいソースバインディングの追加に関するサンプルは 1 つも見つかりませんでした。

更新:
これは、Rio バインディングですぐに使用できるようになりました。これを使用するには、MvvmCross MethodBinding NuGet パッケージをAndroidプロジェクトに追加します。

4

1 に答える 1

3

これまで、MvvmCross の重点の多くは、ソースが主に 'vanilla' のままで、マルチプラットフォームのターゲット バインディングを可能にすることINotifyPropertyChangedでした。

ViewModel 構造に関して、いくつかの逸脱がありました。例:

最近、いくつかの新機能のリクエストもこの領域に記録されています。

これらの理由から、将来この分野でさらに多くの機能が公開されることを期待しています...


そうは言っても、今日これを機能させたい場合は、MvvmCross バインディングがオーバーライド可能であるため、かなり簡単に実行できます。

1. リフレクションを使用して MethodInfo を呼び出す an を実装ICommandします (完全を期すために、利用可能な場合はパラメーターも使用する必要があります) - ある種のInvokeMethodCommand(このコードは読者に任せます!)

.

2. 次のような - MyMethodSourceBindingをラップ するクラスを実装します。InvokeMethodCommand
public class MyMethodSourceBinding : MvxSourceBinding
{
    private readonly MethodInfo _methodInfo;

    protected MyMethodSourceBinding(object source, MethodInfo methodInfo)
        : base(source)
    {
        _methodInfo = _methodInfo;
    }

    public override void SetValue(object value)
    {
        // do nothing - not allowed
    }

    public override Type SourceType
    {
        get { return typeof(ICommand); }
    }

    public override bool TryGetValue(out object value)
    {
        value = new InvokeMethodCommand(source, _methodInfo);
        return true;
    }
}
IMvxSourceBindingFactory3.メソッドが存在することを検出できる独自の実装で 登録されたMvvmCrossをオーバーライドします-悲しいことに、これのほとんどは今日カットアンドペーストコーディングです-それは次のようになります
public class MySourceBindingFactory
    : IMvxSourceBindingFactory
{
    private IMvxSourcePropertyPathParser _propertyPathParser;

    private IMvxSourcePropertyPathParser SourcePropertyPathParser
    {
        get
        {
            if (_propertyPathParser == null)
            {
                _propertyPathParser = Mvx.Resolve<IMvxSourcePropertyPathParser>();
            }
            return _propertyPathParser;
        }
    }

    public IMvxSourceBinding CreateBinding(object source, string combinedPropertyName)
    {
        var tokens = SourcePropertyPathParser.Parse(combinedPropertyName);
        return CreateBinding(source, tokens);
    }

    public IMvxSourceBinding CreateBinding(object source, IList<MvxPropertyToken> tokens)
    {
        if (tokens == null || tokens.Count == 0)
        {
            throw new MvxException("empty token list passed to CreateBinding");
        }

        var currentToken = tokens[0];
        if (tokens.Count == 1)
        {
            return CreateLeafBinding(source, currentToken);
        }
        else
        {
            var remainingTokens = tokens.Skip(1).ToList();
            return CreateChainedBinding(source, currentToken, remainingTokens);
        }
    }

    private static MvxChainedSourceBinding CreateChainedBinding(object source, MvxPropertyToken propertyToken,
                                                                    List<MvxPropertyToken> remainingTokens)
    {
        if (propertyToken is MvxIndexerPropertyToken)
        {
            return new MvxIndexerChainedSourceBinding(source, (MvxIndexerPropertyToken) propertyToken,
                                                          remainingTokens);
        }
        else if (propertyToken is MvxPropertyNamePropertyToken)
        {
            return new MvxSimpleChainedSourceBinding(source, (MvxPropertyNamePropertyToken) propertyToken,
                                                         remainingTokens);
        }

        throw new MvxException("Unexpected property chaining - seen token type {0}",
                               propertyToken.GetType().FullName);
    }

    private static IMvxSourceBinding CreateLeafBinding(object source, MvxPropertyToken propertyToken)
    {
        if (propertyToken is MvxIndexerPropertyToken)
        {
            return new MvxIndexerLeafPropertyInfoSourceBinding(source, (MvxIndexerPropertyToken) propertyToken);
        }
        else if (propertyToken is MvxPropertyNamePropertyToken)
        {
            //**************************
            // Special code is here

            var propertyToken = (MvxPropertyNamePropertyToken) propertyToken;

            if (source != null)
            {
                var method = source.GetType().GetMethod(propertyToken.PropertyName, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
                if (method != null)
                {
                     return new MyMethodSourceBinding(source, method);
                }
            }  
            return new MvxSimpleLeafPropertyInfoSourceBinding(source,
                                                                  (MvxPropertyNamePropertyToken) propertyToken);

            // Special code ends here
            //**************************
        }
        else if (propertyToken is MvxEmptyPropertyToken)
        {
            return new MvxDirectToSourceBinding(source);
        }

        throw new MvxException("Unexpected property source - seen token type {0}", propertyToken.GetType().FullName);
    }
}
4. このソース バインディング ファクトリを独自のカスタム バインディング ビルダーに提供します。例:
public class MyAndroidBindingBuilder
    : MvxAndroidBindingBuilder
{
    protected override IMvxSourceBindingFactory CreateSourceBindingFactory()
    {
        return new MvxSourceBindingFactory();
    }
}
5.セットアップ中にこのバインディングビルダーを提供します
public class Setup : MvxAndroidSetup
{
    // ....

    protected override MvxAndroidBindingBuilder CreateBindingBuilder()
    {
        return new MyAndroidBindingBuilder();
    }
}

注: このアプローチは現在、上級ユーザーのみを対象としています...この質問の最初の部分で示唆されているように、この領域のコードはかなり変更されると予想されるため、この領域でフォークを維持する際に問題が発生する可能性もあります。 . (実際、この領域のコードは、GitHub リポジトリ内の Tibet Binding ブランチですでに大幅に変更されています!)

于 2013-06-27T23:25:06.207 に答える