MvvmCross Implementation of Android RatingBar

本文关键字:RatingBar Android of Implementation MvvmCross | 更新日期: 2023-09-27 18:35:59

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

无法在此控件上进行双向绑定,我怀疑我应该以与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 等控件上的双向绑定问题的推荐方法?

MvvmCross Implementation of Android RatingBar

MvvmCross 双向绑定"仅适用于"任何提供遵循"已更改"模式的属性 API 的控件,如下所示:

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

对于不遵循此约定或使用专用事件处理程序的控件,您必须:

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);
    }
}

然后,可以在安装期间使用以下代码注册此"目标绑定":

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

对于RatingBar,我认为这两种方法中的任何一种都有效......我认为回到核心项目供其他人使用也是有用的。

仅供参考,评级目标绑定内置在较新版本的 Mvx 中,如下所示: 本地列表:MvxBind binder