使用MVVMCross绑定到错误消息

时间:2013-07-08 19:30:45

标签: xamarin.ios mvvmcross

我是MVVMCross(以及一般移动设备)的新手,我希望实现对错误消息的绑定(如FluentValidation ValidationResults或IDataErrorInfo)。

最好,我想像字典一样的错误,我可以直接绑定到: bind(label).To(vm => vm.Errors["Name"])

我尝试过ObservableDictionary(http://blogs.microsoft.co.il/blogs/shimmy/archive/2010/12/26/observabledictionary-lt-tkey-tvalue-gt-c.aspx),但是当ViewModel添加错误时我没有得到通知。

正如所料,在视图模型中将访问包装为属性可以正常工作,但可能会变得很麻烦: public string NameError { get { return Errors.ContainsKey("Name") ? Errors["Name"] : null; } }

我还考虑过创建自定义绑定,但我不确定如何访问ViewModel并传递我想要的字段名称。好像我可以传递错误或属性名称。

最后,由于无效的转换(即,对于int来说是22ab)没有被推入视图模型,是否有办法获得这些错误?我应该在数据被推回到视图模型之前进行验证吗?像iOS上的textFieldShouldEndEditing或ShouldChangeCharacters一样?如果需要,我可以包装自定义控件。

其他人使用Xamarin / MVVMCross提供验证反馈的技术是什么?

提前致谢。

1 个答案:

答案 0 :(得分:3)

MvvmCross目前没有实现数据绑定的IDataErrorInfo级别

这主要是因为没有人要求它 - 但我想这可能会随着这个问题而改变。如果你确实有特定的要求,那么项目就会有兴趣听到它们 - 怀疑最好的地方就是项目的github问题。

针对您的具体问题......


绑定到实现ObservableDictionaryINotifyCollectionChanged的{​​{1}}的方法应该有效。

但是,查看链接中的代码,我认为字典没有正确实现INotifyPropertyChanged - 除了INotifyPropertyChanged事件之外,它还应该提升属性更改INotifyCollectionChangedCount上的通知 - 如果没有这些,则对整个集合的绑定将起作用,但不会对单个项目起作用并进行计数。有关ObservableCollection的示例源,请参阅https://github.com/mosa/Mono-Class-Libraries/blob/master/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs

再次查看链接中的代码,看来字典正在正确实现Item[] - 它正在提升属性更改通知INotifyPropertyChanged - 这是个人所需的字符串要绑定的项目。您是否启用了调试跟踪?跟踪是否能为您提供有关失败原因的线索?

我今天提交了一些修补程序 - https://github.com/slodge/MvvmCross/issues/345 - 并在此示例中对它们进行了测试 - Test_WithErrors.axml - 我希望这个相同的示例应该可以在iOS上运行(iOS测试应用是一项工作杰里米出色的FluentValidation(尽管我还没有用过PCL形式),但它也应该是可扩展的。

Item[]

感谢你指出这个错误 - 修复后的二进制文件会在第二天或第二天出现!


在int-string问题上,绑定层当前“做到最好”(TM)将UI类型转换为VM类型。但是,当它失败时当前没有触发事件 - 因此无法从绑定中触发ViewModel中的任何验证规则。

相反,在允许自由文本输入的情况下,我认为您需要将ViewModel类型实现为 <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Enter email:" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="30dp" local:MvxBind="Text Email" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#ff0000" local:MvxBind="Text Errors['Email']" /> ,然后需要在ViewModel属性更改时触发验证规则。因为MvvmCross在验证发生时没有暴露任何绑定级钩子,所以你可能需要在绑定发生时进行调整(例如在第一响应者辞职时)而不是进行连续验证 - 但这应该是相当直接的,使用自定义 - 结合。