注意MVVM纯粹主义者:ViewModel应该访问本地化资源吗?

时间:2011-11-18 14:28:49

标签: wpf mvvm localization

我有时难以理解ViewModel的目的,特别是关于它应该和不应该做什么。

所以......我发现自己想要从我的ViewModel中公开一个显示字符串。好的,实际上它是一个日期字符串,我希望显示类似于"未知"如果日期没有设定。我真的想要一个解决方案来涵盖一般情况,所以我不想讨论使用null和fallback值。它同样可以是一个状态信息,例如" Awaiting Dispatch"或"启动中止"。

所以问题是,ViewModel应该如何向View公开显示字符串。应用程序需要本地化,因此我们无法在ViewModel中使用硬编码字符串。

可以从ViewModel访问应用程序的资源,并返回显示字符串吗?

顺便说一下,我应该使用resx字符串资源还是Xaml资源字典?我倾向于Xaml。优点/缺点?

谢谢, 标记

5 个答案:

答案 0 :(得分:9)

您正在做的是获取系统内部的数据并将其转换为一种格式,使用户更加有用和清晰。这是观点的责任。视图的责任是将有效日期格式化为正确的文化,并且对您希望显示的任何文本负有相同的责任。

在同样的方面,您提供的状态示例可能会作为枚举存储在视图模型中(因为这样可以更容易地将业务逻辑应用于它们,这是视图模型的作用)并且它将是责任视图以在各方面为用户工作的方式显示值。这包括尺寸,颜色,字体,位置文化。

尽管如此,我知道将显示逻辑放在我的viewmodel中(例如连接firstname和surname)只是因为它更容易。我甚至已经知道使用代码隐藏(震惊,恐怖!),它适合我的目的。纯洁与实用主义之间存在着滑动的尺度,你坐在那条线上取决于你。

答案 1 :(得分:9)

正如其他答案所述,这显然是观点的责任。视图模型应公开要检查的视图的数据属性(状态枚举或类似内容),以便确定显示消息的详细信息。从纯粹主义者的角度来看,从VM或后面的代码生成显示属性是正确的。

但是,我很惊讶听不到数据操纵者的建议。在TextBlock中使用它们绑定到公开的状态枚举值并相应地更新文本。 This question compares their performance against binding to a converter并建议触发器在此方案中表现更好。我自己没有做过任何测试,所以我不确定,但对我来说这似乎是直觉上合理的,前提是你没有听取过多的不同枚举值。在这种情况下,我也认为这是更合适的方法,我会引用this question asking for a comparison of VC vs. DT use cases,尽管我不认为这是非常有争议的。换句话说, 如果 ,我认为VM是类固醇的价值转换器(我非常怀疑并且不同意或不同意的声明)那一刻),然后这个论点成立:VM不应该暴露显示属性; VM的目的和能力是VC的超级集合;因此,VC不应该暴露显示属性。

我正在尽力给出纯粹主义者的答案(或者我认为至少是这样),但是编写代码肯定比编写大量数据触发器更简单,特别是如果你有很多不同的值地址。

关于您的资源问题,请查看this MSDN article on resource files,这在某种程度上比resx文件更易于使用。您应该使用哪种方法取决于您的使用案例。

答案 2 :(得分:3)

在未设置日期时显示字符串Unknown是显示问题,因此必须在视图中解决。甚至“等待派遣”也是一种价值的呈现。

所以答案是:视图模型不应该公开 display 字符串。视图模型必须公开一个值,该值引导视图/转换器/表示层中的任何对象选择显示字符串。

即使这个答案不是您想要阅读的答案,也是MVVM纯粹主义者必须给出的答案。当你要求MMVM纯粹主义者时,就是这样。

答案 3 :(得分:1)

对于日期,我会让ViewModel导出一个可为空的DateTimeOffset,其中null值表示“未设置”。在视图中(通过转换器或类似物),空值显示为您需要的任何内容。

暂且不说:我会使用resx。原因是当字符串在语言中不可用时,存在定义的回退机制。

答案 4 :(得分:1)

我采取的一种方法是创建特定于文化的资源,并将这些实例(单例?)添加到ViewModel中。

然后View可以简单地绑定到ViewModel.Resource.DisplayString

See this article for Windows Phone 7可轻松转换为WPF。

如果您不喜欢这个,因为您不想将特定于文化的资源绑定到ViewModel并希望View解决它,您可以使用/编写一个ValueConverter,将值从VM属性转换为显示字符串。