我正在做一些我以前从未尝试过的事情。我正在尝试创建动态用户界面并将其绑定(bind)到动态模型。换句话说,我的 Web 服务将发回 UI 的小型元数据描述以及要绑定(bind)到它的原始数据。因此,在构建时,我不知道我将构建什么 UI,也不知道我的模型是什么。将它们结合在一起似乎非常困难,甚至不可能。
Mvx 允许我将 UI 直接绑定(bind)到模型,而不需要它是 MvxViewModel。但是,如果我直接绑定(bind)到 Web 服务返回的模型,我将失去 RaisePropertyChanged() 的能力,因为它仅来自 MvxViewModel。
通常,我会编写一个 ViewModel 来包装模型,并让所有包装的 setter 调用 RaisePropertyChanged()。但是,在这种情况下,我的模型是动态的,因此我无法在编译时用 ViewModel 包装它,因为直到运行时我才知道它是什么。
是否有一些很酷的技巧可以用来构造一个 ViewModel,它可以包装任何 C# 模型类并发送属性更改事件,而无需知道模型类在运行时具有哪些属性?
我刚刚发现了 DLR 和 DynamicObject,它们似乎很完美,但由于 Apple 的限制,它无法在 Xamarin.iOS 上运行。
最佳答案
在不将 DynamicObject
融入 iOS 上的情况下,主要考虑的方法是:
您可以更改您的网络服务生成代码,以便它生成
INotifyPropertyChanged
- 我已经使用了执行此操作的库 - 例如http://stacky.codeplex.com/SourceControl/latest#trunk/source/Stacky/Entities/Answer.cs - 如果您无法更改 Web 服务代码生成本身,您仍然可以使用某种 t4 或其他模板技巧来包装或破坏生成的代码。您可以研究某种将 Web 服务对象映射到某种可观察集合的代码(Kiliman 在评论中建议了这一点)
您可以查看某种执行绑定(bind)的 valueconverter (或者可能是 valuecombiner) - 我可以很容易地想象一个 valueconverter 接受一个包装的模型对象和一个字符串参数(属性名称)并使用这些参数两个人一起(经过一些思考)来决定要做什么。我不确定这个如何与嵌套模型对象一起工作...但即使这样也是可能的...
您可以查看 MvvmCross 的某种自定义绑定(bind)扩展。这并不像听起来那么可怕,但确实需要一些反射技巧 - 要了解可能涉及的内容,请查看 FieldBinding 插件 - https://github.com/MvvmCross/MvvmCross-Plugins/tree/master/FieldBinding
在实际的数据绑定(bind)过程中,该插件将通过
IMvxSourceBindingFactoryExtension
调用 - 这将是您 Hook 某些其他自定义更改事件
(而不是INotifyPropertyChanged
)。可能需要一些实验才能做到这一点......特别是如果您有嵌套对象(然后需要在绑定(bind)内“链接”)......但我认为应该可以通过这种方式产生一些东西。
关于dynamic - 没有 ViewModel 的数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33292281/