Is two-way binding supported on MVVMCross for Touch? (besides UITextFields)

陌路散爱 提交于 2019-12-22 13:51:27

问题


I was looking at reasons why my 2-way binding hasn't been working for iOS development using MVVMCross. I'm using UITextViews embedding in custom cells of a tableView.

I've looked at this question:

How do I do two-way binding to a UITextView control using mvvmcross?

and there was mention on how 2-way binding with UITextViews isn't supported in Vnext, but it is in beta with V3 (Hot Tuna). I am using Hot Tuna, and got the binaries approx. June 12th.

The following line of code is how I'm binding my cell.

this.CreateBinding (_cells[2]).For (cll => cll.FieldDescription).To ((TimesheetViewModel vm) => vm.AccountID).Mode(MvxBindingMode.TwoWay).Apply ();

_cells[] is an array of custom class cells

Here's the property of FieldDescription in my custom cell class: (FieldDescriptionLabel is my UITextView)

    public string FieldDescription
    {
        get
        { 
            return FieldDescriptionLabel.Text;
        }
        set 
        {
            FieldDescriptionLabel.Text = value;
        }
    }

My UITextView binds one way; I do see the information populated from my viewModel, but when I change something in the UITextView, the ViewModel doesn't reflect those changes.

So the main question: Is 2-way binding working for UITextView in MVVMCross Hot Tuna? If yes, any ideas on what I'm doing wrong in my implementation?

Appreciate it!


回答1:


In order for two-way binding to work, mvvmcross needs to know when the ui value changes.

There are a couple of ways to do this.

Perhaps the easiest way, given your current setup, is to add a public event EventHandler FieldDescriptionChanged to your cell and to make sure this event is fired every time the text view changes - e.g. with code like.

public event EventHandler FieldDescriptionChanged;

public string FieldDescription
{
    get
    { 
        return FieldDescriptionLabel.Text;
    }
    set 
    {
        FieldDescriptionLabel.Text = value;
    }
}

public override void AwakeFromNib()
{
    base.AwakeFromNib();

    FieldDescriptionLabel.Changed += (s,e) => {
        var handler = FieldDescriptionChanged;
        if (handler != null) 
            handler(this, EventArgs.Empty);
    };
}

Alternatively, you could try basing your cell on the Mvx table view cells which have an inherent DataContext. If you do this, then you can bind directly to the UITextView with and then using data-binding within the cell's context.

This approach is shown in the N+1 tutorials - for example in N=6.5 - http://slodge.blogspot.co.uk/2013/05/n6-books-over-network-n1-days-of.html - where the cell ends up with a constructor like:

public BookCell (IntPtr handle) : base (handle)
{
    _loader = new MvxImageViewLoader(() => MainImage);

    this.DelayBind(() => {
        var set = this.CreateBindingSet<BookCell, BookSearchItem> ();
        set.Bind(TitleLabel).To (item => item.volumeInfo.title);
        set.Bind (AuthorLabel).To (item => item.volumeInfo.authorSummary);
        set.Bind (_loader).To (item => item.volumeInfo.imageLinks.thumbnail); 
        set.Apply();
    });
}

Using this approach, you would simply need to bind the cell's data context - e.g. something like:

   this.CreateBinding (_cells[2]).For (cll => cll.DataContext).To ((TimesheetViewModel vm) => vm).TwoWay().Apply ();


来源:https://stackoverflow.com/questions/17156368/is-two-way-binding-supported-on-mvvmcross-for-touch-besides-uitextfields

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!