1

我一直在将现有应用程序转换为使用 MvvmCross (HotTuna),而我使用过的其中一个 Android 控件是 RatingBar。

我无法在此控件上进行 2 向绑定,我怀疑我应该以与 Cirrious.MvvmCross.Binding.Droid.Views 下的其他 Android 控件类似的样式实现 MvxRatingBar。

目前仅使用标准绑定我有以下代码:

    <RatingBar
    style="@style/scoreRatingBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:isIndicator="false"
    android:paddingTop="5dp"
    local:MvxBind="Max OutOf; NumStars OutOf; Rating ScoreA, Mode=TwoWay" />

我的问题是,这是解决RatingBar 等控件上双向绑定问题的推荐方法吗?

4

2 回答 2

1

MvvmCross 双向绑定对于任何提供遵循“已更改”模式的属性 API 的控件“都有效”,例如:

public PType MyProperty { get; set; }
public event EventHandler MyPropertyChanged;

对于不遵循此约定或使用专用 EventHandler 的控件,您必须:

1.从控件继承,并在继承的控件类中提供模式

public class ExtraThing : Thing
{
    public ExtraThing(Context c, IAttributeSet attrs)
         : base(c, attrs)
    {
    }

    protected override SomethingChanged()
    {
        MyPropertyChanged.Raise(this);
    }

    public PType MyProperty
    {
       get { return base.Something(); }
       set { base.ChangeSomething(value); }
    }

    public event EventHandler MyPropertyChanged;
}

2.或者提供自定义目标绑定

这在http://slodge.blogspot.co.uk/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html中有完整的讨论

基本上需要的代码是用于自定义“目标绑定”的,它知道如何获取/设置属性以及如何观察其变化:

public class ThingMyPropertyTargetBinding : MvxAndroidTargetBinding
{
    protected Thing Thing
    {
        get { return (Thing) Target; }
    }

    public ThingMyPropertyTargetBinding (Thing target) : base(target)
    {
    }

    public override void SubscribeToEvents()
    {
        Thing.MyPropertyChanged += TargetOnMyPropertyChanged;
    }

    private void TargetOnMyPropertyChanged(object sender, SpecialEventArgs eventArgs)
    {
        var target = Target as Thing;

        if (target == null)
            return;

        var value = target.GetMyProperty();
        FireValueChanged(value);
    }

    protected override void SetValueImpl(object target, object value)
    {
        var binaryEdit = (Thing)target;
        binaryEdit.SetMyProperty((PType)value);
    }

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

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

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            var target = Target as BinaryEdit;
            if (target != null)
            {
                target.MyPropertyChanged -= TargetOnMyPropertyChanged;
            }
        }
        base.Dispose(isDisposing);
    }
}

然后可以在设置期间使用以下代码注册此“TargetBinding”:

    protected override void FillTargetFactories(Cirrious.MvvmCross.Binding.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
    {
        registry.RegisterCustomBindingFactory<Thing>(
                        "SpecialBinding",
                        thing => new ThingMyPropertyTargetBinding (thing) );
        base.FillTargetFactories(registry);
    }

因为RatingBar,我认为这两种方法中的任何一种都行得通……而且我认为回到核心项目供其他人使用也会很有用。

于 2013-10-18T09:37:12.820 回答
1

仅供参考,评级目标绑定是在较新版本的 Mvx 中构建的,您可以在此处看到:本地列表:MvxBind 绑定器

于 2015-11-09T03:05:42.377 回答