gpt4 book ai didi

mvvmcross - 绑定(bind)到 Action 方法

转载 作者:行者123 更新时间:2023-12-04 04:51:37 24 4
gpt4 key购买 nike

是否可以使用简单的操作方法——就像使用 Caliburn.Micro 一样——而不是使用 MvvmCross 绑定(bind)的命令?

例子:

    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" />

它不能开箱即用,我测试过。

虽然我发现了很多关于添加新目标绑定(bind)的示例,但我没有找到一个关于添加新源绑定(bind)的示例。

更新:
现在使用 Rio 绑定(bind)开箱即用。要使用它,请将 MvvmCross MethodBinding NuGet 包添加到 Android 项目。

最佳答案

到目前为止,MvvmCross 的大部分重点一直是允许多平台目标绑定(bind),而源代码仍然主要是“ Vanilla ”INotifyPropertyChanged .

ViewModel 结构存在一些偏差 - 例如:

  • MvxCommandCollection - http://slodge.blogspot.co.uk/2013/03/fixing-mvvm-commands-making-hot-tuna.html
  • 一些使用 Fody 的用户 - http://twincoders.com/blog/codigo-limpio-con-fody/

  • 最近,该区域还记录了几个新功能请求:
  • AutoCommands - 我想这就是你在这里问的 - https://github.com/slodge/MvvmCross/issues/301
  • Rio 绑定(bind)源 - https://github.com/slodge/MvvmCross/issues/299
  • 西藏装订- https://github.com/slodge/MvvmCross/issues/298

  • 正因为如此,我确实希望将来会在该领域公开更多功能......

    话虽如此,如果你想今天让它工作,那么 MvvmCross Binding 是可覆盖的,所以你可以很容易地做到这一点:

    1. 实现 ICommand使用反射调用 MethodInfo(为了完整起见,如果可用,也应该使用参数)- 某种 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;
    }
    }

    3.覆盖MvvmCross注册的 IMvxSourceBindingFactory使用您自己的实现可以检测何时存在方法 - 遗憾的是,今天大部分都是剪切和粘贴编码 - 它就像
    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. 在您​​自己的自定义绑定(bind)构建器中提供此源绑定(bind)工厂 - 例如:
    public class MyAndroidBindingBuilder
    : MvxAndroidBindingBuilder
    {
    protected override IMvxSourceBindingFactory CreateSourceBindingFactory()
    {
    return new MvxSourceBindingFactory();
    }
    }

    5. 在设置期间提供此绑定(bind)生成器
    public class Setup : MvxAndroidSetup
    {
    // ....

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

    注意:此方法目前仅适用于高级用户...正如本问题第一部分所建议的那样,我确实希望该区域的代码会发生很大变化,因此您可能还会遇到维护该区域分支的一些问题. (事实上​​,这方面的代码在 GitHub 存储库中的西藏绑定(bind)分支上已经发生了相当大的变化!)

    关于mvvmcross - 绑定(bind)到 Action 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17351375/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com