2014-04-26 4 views
2

J'ai essayé de lier un widget à une propriété viewmodel mais je reçois une exceptionMvvmcross Reliure

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 

Le widget est une gracieuseté de Al taiar

Le AXML est

<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" /> 

Le le code pour la vue est

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

Et le code pour le modèle est

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

je besoin de deux voies de liaison pour ce widget. Quelqu'un veut-il aider ???

Je devrai également ajouter un texte «Clear» en superposition sur la vue. Cliquer sur ce texte déclenchera une commande pour effacer le widget. Toute idée de comment faire cela?

P.S: J'ai suivi le post informatif et je ne peux toujours pas le faire fonctionner. J'ai ajouté ce qui suit.

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; 
     } 
    } 
} 

et enregistré à l'aide

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

Répondre

0

MvvmCross se liera automatiquement Voir propriété si vous le modèle en utilisant le format:

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

    public event EventHandler BarChanged; 

Sur la base de cela, je pense que votre problème est que vous essayez d'utiliser un champ - public Signature Signature; - essayez d'utiliser une propriété à la place.

Je pense que le mode de liaison que vous recherchez est aussi le OneWayToSource inhabituel au lieu de TwoWay

+0

Je suis sûr que je suis venu à travers ce conseil dans les messages que j'ai lu, je suppose que je devais avoir surchargé de travail ne pas remarquer cette erreur. Merci beaucoup. – Telemat

+0

Bar serait une copie ou devrait-il pointer vers la propriété VM? – Telemat