【发布时间】:2016-07-19 19:45:06
【问题描述】:
在为一些学徒准备研讨会时,我遇到了一个问题,即在遵循 MVVM 模式时保存当前状态。
环境
首先是用于此问题的类图:
其次是GUI,所以你可以想象我期望用户做什么:
MainMV 为每种成分(硬编码)创建一个成分VM,并将它们添加到列表中。 然后这个列表绑定到 UI。随着用户更改复选框状态,IngredientVM 的“IsChecked”属性也会相应更改。
通过 UI 选择的成分被保存在 Pizza 对象中。所以比萨对象包含所选成分的列表。
问题
用户应该能够导出和导入他的选择。这听起来很容易做,但问题在于我想在本练习中使用的 MVVM 模式。
由于我已经设置了成分列表,因此我已经有了这些类的实例。如果我通过序列化保存和加载它们,我会得到序列化类的另一个实例。所以我最终得到了一个所有成分的列表和一个包含两个不同对象的所选成分的列表!
可能的解决方案
我遇到了一些解决方案,但我不知道哪一个最适合 MVVM 模式的理念:
-
根据导入的成分对象设置复选框状态。
这意味着我检查导入的成分名称是否与其中一个成分VM中的名称相同。如果是这样,我将 IsChecked 设置为 true。
但我觉得这是一种非常糟糕的编码方式。 -
序列化所有成分虚拟机
我只是序列化上一层。这样我就可以得到所有成分的状态(检查与否)。
此解决方案的缺点是,如果用户加载较旧的保存文件,则只会加载旧的成分,因为它会使通常的“createIngrediants”过程过载。 -
仅导出 ID
在我看来,这是迄今为止最合适的解决方案。我只导出所选成分的 ID。 (当然,我必须先将 id 添加到类中)在导入时,我只是在列表中查找 id 并将其设置为选中。
但不知何故,我觉得将 id 添加到像成分这样简单的东西是错误的...
那么,你们有没有更好的解决这个问题的方法?
感谢您的意见!
【问题讨论】:
-
如果您想要更好的答案,您必须提供代码。有人会接受并修改以显示错误所在。而且我认为您有设计问题:当有人想要订购 2 种不同的比萨饼(具有不同的成分)时,您会怎么做?
-
@Sinatr 我没有故意提供代码,因为我不希望人们关注代码而是设计。不止一个披萨:然后他必须定义一个披萨,导出然后定义另一个。这只是一个学徒项目。
-
如果你添加
Order,那么你会看到设计错误。您不应该直接引用Ingredient,因为它们的IsChecked在所有比萨饼中都是相同的。和 2 个解决方案:1)当您将新披萨添加到订单时复制所有成分列表 2)使用 id 引用它们。如果这样做,反序列化将没有问题。 -
@Sinatr 成分不包含 IsChecked 属性。 IngredientVM 可以。但是是的,就像 Siderite Zackwehdex 提到的那样,添加一个 id 似乎是迄今为止最好的解决方案。
标签: c# wpf serialization mvvm