如何从ViewModel实例化视图

本文关键字:实例化 视图 ViewModel | 更新日期: 2023-09-27 18:00:47

在我们的模型和ViewModel中发生的事件需要创建适当的视图。问题是如何做到这一点,并避免在VM或M中有任何View代码?

以下是事件的顺序,因此您可以看到这种困境:

用户在表单中设置一个数字字段以启动一个长时间运行的后台进程,然后单击"启动"按钮。如果这个长时间运行的过程成功了,那么它需要弹出一个图表来显示结果。然而,如果数据由于任何原因无法处理,那么它就不能弹出图表,而是记录一条错误消息,显示在表单的文本框中。

现在,启动按钮调用ViewModel中的一个方法,该方法实际上启动了后台线程。

只有背景才能决定何时或是否创建视图。

目前,我们通过使用一个名为ChartInterface的接口来实现这一点。视图实现了这个接口,然后设置一个回调委托,一直到后端模型。当它决定创建图表时,它会调用回调并使用接口传递适当的数据等。

然而,这带来了一个问题,因为它可能会生成数十或数百张图表。因此,我们需要一个"仪表板",其中包含所有图表的列表,供用户选择要查看的图表。

因此,现在后端需要决定何时或是否创建仪表板视图,然后将图表视图添加到其中。

所以它变得越来越混乱,因为我们有很多模型需要视图,所以创建大量的回调委托会很快变得很难看,所以这种情况会越来越多。

一个似乎可以简化而不是大量回调的想法是,只将ViewBinder的接口传递到后端。然后,每次创建模型对象时,它都可以将其传递给ViewBinder,看看是否要将任何视图对象绑定到它

我们的想法是,大多数后端对象(最终)都会对图形监控感兴趣。因此,如果构建后的每个视图都被传递到ViewBinder接口,那么视图就可以决定是否要将任何内容绑定到它。

这听起来一直都比较好。

如何从ViewModel实例化视图

在编写代码时,答案变得清晰起来。

公共接口ModelBinderInterface{void TryBind(对象模型);}

每个视图对象实现这个接口更自然,而不是一个全局的"服务器定位器"。

然后,当它创建任何ViewModel对象时,它会将自己指定给ViewModel对象的ModelBinder属性。

现在ViewModel可以将这个相同的接口传递给后端进程。

当任何相关的模型被实例化时,它就会调用带有该对象的ModelBinder。

然后,View对象可以决定是否可以实例化对象,如果不能,则可以将调用传递给它的父对象,该父对象也实现ModelBinderInterface。

通过这种方式,每个视图都可以处理它所理解的实例化视图,无论是将控件添加到DataGridView还是将对象绑定到ListView,等等。

当然,这仍然允许使用singleton ModelBinder,因为较低级别的应用程序可以继续将调用交给顶层应用程序ModelBinder(只有一个),并且它可以提供singleton实例。