2014-04-26 3 views
2

Я попытался связать виджет с ViewModel собственности, но я получаю исключениеMvvmcross Связывание

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

ответ

0

MvvmCross автоматически связать Просмотреть свойство если вы смоделировали его, используя формат:

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

    public event EventHandler BarChanged; 

Исходя из этого, я думаю, ваша проблема в том, что вы пытаетесь использовать поле - public Signature Signature; - попробуйте использовать свойство вместо этого.

Я думаю связывание режима вы ищете также необычный OneWayToSource вместо TwoWay

+0

Я уверен, что я наткнулся на этом посоветуйте в постах, которые я читал, я предполагаю, что я должен был перегружен чтобы не заметить эту ошибку. Огромное спасибо. – Telemat

+0

Может ли Bar быть копией или указывать на свойство VM? – Telemat

Смежные вопросы