我一直在转换现有应用程序以使用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双向绑定对于所有提供“遵循”“更改”模式的属性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,我认为这两种方法中的任何一种都行得通……而且我认为回到核心项目中以供其他人使用也很有用。

关于c# - Android RatingBar的MvvmCross实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19445858/

10-10 02:01