我是MVVMCross(Xamarin.iOS)的新手。所以,我可能走错方向。如果有人可以指出我正确的方向或指出我做错了什么。
我已经看过MVVMCross的“CustomerManagement”和“Collection”样本。
基本上我正在尝试创建“设置”屏幕。
我有一个带有一个文本字段的自定义UITableViewCell。请参阅下面的代码。 “EntryTF”是IBOutleted。 “EntryTF”与Model的“FirstName”属性绑定。将值设置为“FirstName”反映在UI上。但是,如果用户输入文本字段的东西不保存到模型。简而言之,单元格不会更新viewmodel / model。
请注意我想保持绑定细胞类。因此,我可以将此单元格重用于其他模型或字段。
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; }
}
TableView来源:
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,但对自定义单元格并没有多大用处,而且还需要我很多学习。
答案 0 :(得分:2)
基本上我正在尝试创建设置屏幕。
看看使用montouch对话框mt.d和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();
});
}
}
答案 1 :(得分:1)
Your custom cell needs to implement INotifyPropertyChanged to allow the ViewModel to be notified of a value change in your cell properties.
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
}