3

我是 MVVMCross(Xamarin.iOS)的新手。所以,我可能走错了方向。如果有人能指出我正确的方向或指出我做错了什么。

我已经查看了 MVVMCross 的“CustomerManagement”和“Collection”示例。

基本上我正在尝试创建设置屏幕。

我有一个带有一个文本字段的自定义 UITableViewCell。请参阅下面的代码。“EntryTF”是 IBOutleted。“EntryTF”与 Model 的“FirstName”属性绑定。将值设置为“FirstName”反映在 UI 上。但是,如果用户在文本字段中输入内容不会保存到模型。简而言之,单元格没有更新视图模型/模型。

请注意,我想保持绑定在单元格之外。因此,我可以将此单元格重用于其他模型或字段。

public partial class PlainEntryCell : UITableViewCell
{
    public static readonly UINib Nib = UINib.FromName ("PlainEntryCell", NSBundle.MainBundle);
    public static readonly NSString Key = new NSString ("PlainEntryCell");

    public PlainEntryCell (IntPtr handle) : base (handle)
    {
  //            this.DelayBind (() => {
 //             this.AddBindings(new Dictionary<object,string> ())
 //         });
    }

    public static PlainEntryCell Create ()
    {
        return (PlainEntryCell)Nib.Instantiate (null, null) [0];
    }

    public string CaptionText {
        get {
            return EntryTF.Text;
        }
        set {
            EntryTF.Text = value;
        }
    }
}

我的视图模型:

public class RegisterViewModel: MvxViewModel
{
    private RegisterModel _registerModel;

    public RegisterViewModel ()
    {
        _registerModel = new RegisterModel ();
        _registerModel.FirstName = "Test";
    }

    public RegisterModel Customer {
        get { return _registerModel; }
        set {
            _registerModel = value;
            RaisePropertyChanged ("Customer");
        }
    }
}

模型:

public class RegisterModel:MvxNotifyPropertyChanged
{
    private string _firstName;

    public string FirstName {
        get { return _firstName; }
        set {
            _firstName = value;
            RaisePropertyChanged ("FirstName");
        }
    }

    public string LastName { get; set; }

    public string PhoneNum { get; set; }

    public string Email { get; set; }

    public string Pin { get; set; }
}

表视图源:

public class RegisterTableViewSource: MvxTableViewSource
{
    RegisterView _registerView;

    public RegisterTableViewSource (UITableView tableView, RegisterView registerView)
        : base (tableView)
    {
        _registerView = registerView;

        tableView.RegisterNibForCellReuse (PlainEntryCell.Nib,
            PlainEntryCell.Key);
        //tableView.RegisterNibForCellReuse (UINib.FromName ("DogCell", NSBundle.MainBundle), DogCellIdentifier);
    }

    protected override UITableViewCell GetOrCreateCellFor (UITableView tableView, Foundation.NSIndexPath indexPath, object item)
    {
        var cell = TableView.DequeueReusableCell (PlainEntryCell.Key, indexPath);
        cell.Bind (_registerView, "CaptionText Customer.FirstName");
        return cell;
        //return (UITableViewCell)TableView.DequeueReusableCell (PlainEntryCell.Key, indexPath);
    }

    public override nint RowsInSection (UITableView tableview, nint section)
    {
        return 2;
    }
}

更新: 仍然无法得到答案。在上面的代码中,我想将“EntryTF”与模型的属性绑定。但我想在课外保持约束力。因此,如果有人可以指出直接绑定到“EntryTF”的方式,则不需要 CaptionText 属性。难道没有像 Xamarin Forms 一样创建 BindableProperty 的方法吗?所以我觉得MVVMCross是成熟的框架,为什么这种简单的事情没有解决方案。

如果有任何简单/其他方法可以实现相同的目标,我也很想在这里。

我也看过 MTD,但没有发现对自定义单元有多大用处,而且它也需要我大量的学习。

4

2 回答 2

2

基本上我正在尝试创建设置屏幕。

看看使用 monotouch dialog, mt.d, with MvvmCross, Use Mvvmcross Binding with MonoTouch.Dialog (Lists and Commands)

StackOverflow 问题/答案将使您开始使用 mt.d 和 mvvmcross。我将它用于我的应用程序中的基本设置屏幕。

单元格未更新

我写了一篇关于在 MvvmCross 中使用自定义单元的文章,请参阅 http://benjaminhysell.com/archive/2014/04/mvvmcross-custom-mvxtableviewcell-without-a-nib-file/

我发现不使用 nib 文件并在代码中完整描述我的 UI 更容易。

看起来您public partial class PlainEntryCell : UITableViewCell从未将单元格绑定到 ViewModel。您已将其注释掉。我会尝试类似的方法,同时将http://slodge.blogspot.com/2013/07/playing-with-constraints.html添加到您的应用程序进行布局:

 public PlainEntryCell()
        {
            CreateLayout();
            InitializeBindings();
        }

 UILabel captionText;

 private void CreateLayout()
        {            
            SelectionStyle = UITableViewCellSelectionStyle.None;


            Accessory = UITableViewCellAccessory.DisclosureIndicator;          
            captionText = new UILabel();
             ContentView.AddSubviews(captionText);
            ContentView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
            const int vPadding = 10;
            const int hPadding = 20;
            ContentView.AddConstraints(

                captionText.AtTopOf(ContentView).Plus(vPadding),
                captionText.AtLeftOf(ContentView).Plus(hPadding),
                captionText.Width().EqualTo(UIScreen.MainScreen.Bounds.Width / 2)
);

 private void InitializeBindings()
        {
            this.DelayBind(() =>
            {
                var set = this.CreateBindingSet<PlainEntryCell, RegisterViewModel();
                set.Bind(captionText).To(vm => vm.CaptionText);               
                set.Apply();
            });
        }

}
于 2015-06-25T13:12:32.217 回答
1

您的自定义单元格需要实现 INotifyPropertyChanged 以允许 ViewModel 收到单元格属性值更改的通知。

public partial class PlainEntryCell : UITableViewCell, INotifyPropertyChanged
{
    public static readonly UINib Nib = UINib.FromName ("PlainEntryCell", NSBundle.MainBundle);
    public static readonly NSString Key = new NSString ("PlainEntryCell");

    public PlainEntryCell (IntPtr handle) : base (handle)
    {
  //            this.DelayBind (() => {
 //             this.AddBindings(new Dictionary<object,string> ())
 //         });
    }

    public static PlainEntryCell Create ()
    {
        return (PlainEntryCell)Nib.Instantiate (null, null) [0];
    }

    public string CaptionText {
        get {
            return EntryTF.Text;
        }
        set {
            EntryTF.Text = value;
            RaisePropertyChanged("CaptionText");
        }
    }

    #region INotifyPropertyChanged implementation

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}
于 2015-06-26T09:31:34.983 回答