[英]MvvmCross Custom Binding not notified by RaisePropertyChanged
我正在尝试在MvxImageView
(在Android CardView内)上实现可触发的动画,以在更改卡的ViewModel属性时将颜色(绿色或红色)覆盖到图像上。 我在这里使用Stuart Lodge的示例创建了自定义类DynamicImageView。
public class DynamicImageView : MvxImageView
{
public DynamicImageView(Context context) : base(context)
{
}
public DynamicImageView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public DynamicImageView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
}
protected DynamicImageView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
Drawable d = this.Drawable;
if (d != null)
{
// ceil not round - avoid thin vertical gaps along the left/right edges
int width = MeasureSpec.GetSize(widthMeasureSpec);
int height = (int)Math.Ceiling(width * (float)d.IntrinsicHeight / d.IntrinsicWidth);
this.SetMeasuredDimension(width, height);
}
else
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private ObjectAnimator colorFilterAnimation;
private string _animatingColor;
public string AnimatingColor
{
set
{
System.Diagnostics.Debug.WriteLine("Animation triggered");
if (value != _animatingColor)
{
_animatingColor = value;
colorFilterAnimation = ObjectAnimator.OfObject((ImageView)this, "colorFilter", new ArgbEvaluator(), 0, 0);
switch (value)
{
case "red":
colorFilterAnimation.SetObjectValues(0, new Color(100, 0, 0, 80).ToArgb());
System.Diagnostics.Debug.WriteLine("Starting Red Animation");
break;
case "green":
colorFilterAnimation.SetObjectValues(0, (int)Color.Green);
System.Diagnostics.Debug.WriteLine("Starting Green Animation");
break;
}
colorFilterAnimation.SetDuration(1000);
colorFilterAnimation.Start();
}
}
}
}
在此控件的ViewModel中,我还按照标准MvvmCross表示法定义了match属性:
private string _animatingColor;
public string AnimatingColor {
get
{
return _animatingColor;
}
set
{
_animatingColor = value;
Debug.WriteLine("AnimatingColor set to " + value);
RaisePropertyChanged(() => AnimatingColor);
}
}
单击该卡即可更改此属性,当我单击该按钮时,我确实从属性set
看到了Debug打印,但它似乎根本没有触发控件中AnimatingColor的set
。 该控件在axml中正常引用:
<DynamicImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
local:MvxBind="ImageUrl 'http:'+Profile.Headshot.Url; AnimatingColor .AnimatingColor" />
对于它的价值,imageUrl确实可以正确绑定,并且在ViewModel中更改Url时可以按预期更新。 此外,在创建卡时, Debug.PrintLine("Animation triggered")
会打印,但在ViewModel上更改属性时不会打印。
正如评论所建议的,我相信您需要为DynamicImageView控件创建自定义绑定。 这样的事情应该做到:
public class DynamicImageViewAnimatingColorBinding : MvxTargetBinding
{
public DynamicImageViewAnimatingColorBinding(DynamicImageView target) : base(target)
{
}
protected DynamicImageView View => Target as DynamicImageView;
public override MvxBindingMode DefaultMode => MvxBindingMode.OneWay;
public override Type TargetType => typeof(string);
public override void SetValue(object value)
{
var view = View;
if (view == null)
return;
view.AnimatingColor = (string) value;
}
}
然后,在您的Setup类中,您需要注册它,以便MvvmCross可以使用它:
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterCustomBindingFactory<DynamicImageView>(
nameof(DynamicImageView.AnimatingColor),
image => new DynamicImageViewAnimatingColorBinding (image));
base.FillTargetFactories(registry);
}
我尚未测试此代码,它基于我在iOS上使用的一些非常相似的代码,但在Android上应该可以正常工作。 希望这会有所帮助。
James Mundy的问题使我意识到根本的问题是我没有在列表中使用ObservableCollection,因此对基本ViewModels的更改未反映在UI中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.