我一直在转换现有应用程序以使用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/