Mvvmcross绑定

时间:2014-04-26 17:25:05

标签: mvvmcross

我尝试将窗口小部件绑定到viewmodel属性,但是我得到了一个异常

MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature
[0:] MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature
04-26 21:02:15.380 I/mono-stdout(32490): MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature

小部件由Al taiar

提供

axml

<SignatureWidget
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/signatureWidget1"
        android:layout_marginRight="5dp"
        android:layout_marginLeft="5dp"
        android:layout_marginBottom="5dp"
        local:MvxBind="Signature Order.ClientSignature" />

视图的代码是

using Android.Content;
using Android.Graphics;
using Android.Util;
using Android.Views;
using Core.Models;
using System;

public class SignatureWidget
    : View
{
    #region Implementation

    private Bitmap _bitmap;
    private Canvas _canvas;
    private readonly Path _path;
    private readonly Paint _bitmapPaint;
    private readonly Paint _paint;

    private float _mX, _mY;
    private const float TouchTolerance = 4;

    #endregion

    public Signature Signature;

    public event EventHandler SignatureChanged;

    public SignatureWidget(Context context, IAttributeSet attrs)
        : base(context, attrs)
    {
        Signature = new Signature();

        _path = new Path();
        _bitmapPaint = new Paint(PaintFlags.Dither);
        _paint = new Paint
        {
            AntiAlias = true,
            Dither = true,
            Color = Color.Argb(250, 00, 0, 0)
        };
        _paint.SetStyle(Paint.Style.Stroke);
        _paint.StrokeJoin = Paint.Join.Round;
        _paint.StrokeCap = Paint.Cap.Round;
        _paint.StrokeWidth = 5;
    }

    protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
    {
        base.OnSizeChanged(w, h, oldw, oldh);
        _bitmap = Bitmap.CreateBitmap(w, (h > 0 ? h : ((View)this.Parent).Height), Bitmap.Config.Argb8888);
        _canvas = new Canvas(_bitmap);
    }

    protected override void OnDraw(Canvas canvas)
    {
        canvas.DrawColor(Color.White);
        canvas.DrawBitmap(_bitmap, 0, 0, _bitmapPaint);
        canvas.DrawPath(_path, _paint);
    }

    private void TouchStart(float x, float y)
    {
        _path.Reset();
        _path.MoveTo(x, y);
        _mX = x;
        _mY = y;
        Signature.AddPoint(SignatureState.Start, (int)x, (int)y);
    }

    private void TouchMove(float x, float y)
    {
        float dx = Math.Abs(x - _mX);
        float dy = Math.Abs(y - _mY);

        if (dx >= TouchTolerance || dy >= TouchTolerance)
        {
            _path.QuadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
            Signature.AddPoint(SignatureState.Move, (int)x, (int)y);
            _mX = x;
            _mY = y;
        }
    }

    private void TouchUp()
    {
        if (!_path.IsEmpty)
        {
            _path.LineTo(_mX, _mY);
            _canvas.DrawPath(_path, _paint);
        }
        else
        {
            _canvas.DrawPoint(_mX, _mY, _paint);
        }
        Signature.AddPoint(SignatureState.End, (int)_mX, (int)_mY);

        _path.Reset();
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        var x = e.GetX();
        var y = e.GetY();

        switch (e.Action)
        {
            case MotionEventActions.Down:
                TouchStart(x, y);
                Invalidate();
                break;
            case MotionEventActions.Move:
                TouchMove(x, y);
                Invalidate();
                break;
            case MotionEventActions.Up:
                TouchUp();
                Invalidate();
                break;
        }

        RaiseSignatureChangedEvent();

        return true;
    }

    public void ClearCanvas()
    {
        _canvas.DrawColor(Color.White);
        Invalidate();
    }

    public Bitmap CanvasBitmap()
    {
        return _bitmap;
    }

    public void Clear()
    {
        ClearCanvas();
        Signature.Clear();

        RaiseSignatureChangedEvent();
    }

    private void RaiseSignatureChangedEvent()
    {
        var handler = SignatureChanged;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }
}

该模型的代码是

public class Signature
{
    private List<Point> _currentPath;
    private readonly List<List<Point>> _paths;

    public event EventHandler PointAdded;

    public Signature()
    {
        _currentPath = new List<Point>();
        _paths = new List<List<Point>>();
    }

    public IReadOnlyList<IReadOnlyList<Point>> Paths
    {
        get { return _paths; }
    }

    public Point LastPoint()
    {
        if (_currentPath != null && _currentPath.Count > 0)
        {
            return _currentPath.Last();
        }

        return new Point(0, 0);
    }

    public void Clear()
    {
        _paths.Clear();
        _currentPath.Clear();
    }

    public void AddPoint(SignatureState state, int x, int y)
    {
        if (state == SignatureState.Start)
        {
            _currentPath = new List<Point>();
        }
        if (x != 0 && y != 0)
        {
            _currentPath.Add(new Point(x, y));
        }
        if (state == SignatureState.End)
        {
            if (_currentPath != null)
            {
                _paths.Add(_currentPath);
            }
        }

        RaisePointAddedEvent();
    }

    public int Length
    {
        get { return _paths.Count; }
    }

    protected void RaisePointAddedEvent()
    {
        if (PointAdded != null)
            PointAdded(this, EventArgs.Empty);
    }
}

我需要这个小部件的双向绑定。有人在乎帮忙???

我还需要在视图上添加“清除”文本作为叠加层。单击此文本将触发清除窗口小部件的命令。有任何线索如何做到这一点?

P.S: 我已经关注了信息丰富的post,但仍然无法让它发挥作用。我添加了以下内容。

public class SignatureWidgetSignatureTargetBinding
    : MvxPropertyInfoTargetBinding<SignatureWidget>
{
    public SignatureWidgetSignatureTargetBinding(object target, PropertyInfo targetPropertyInfo)
        : base(target, targetPropertyInfo)
    {
        View.SignatureChanged += OnSignatureChanged;
    }

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

    private void OnSignatureChanged(object sender, EventArgs eventArgs)
    {
        FireValueChanged(View.Signature);
    }

    protected override void Dispose(bool isDisposing)
    {
        base.Dispose(isDisposing);
        if (isDisposing)
        {
            View.SignatureChanged -= OnSignatureChanged;
        }
    }
}

并使用

注册
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(SignatureWidgetSignatureTargetBinding), typeof(SignatureWidget), "Signature"));

1 个答案:

答案 0 :(得分:0)

如果您使用以下格式对其进行建模,则Mvv​​mCross会自动绑定View 属性

  public foo Bar {
     get { /* ... your code ... */ }
     set { /* ... your code ... */ }
  }

  public event EventHandler BarChanged;

基于此,我认为您的问题是您尝试使用字段 - public Signature Signature; - 请尝试使用属性。

我认为您正在寻找的绑定模式也不常见OneWayToSource而不是TwoWay