在模型层中,我定义了一个枚举:
public enum MemberStatus
{
ActiveMember = 0,
InactiveMember = 1,
Associate = 2,
BoardMember = 3,
Alumni = 4
}
在我看来,我有一个用这些枚举值填充的组合框:
<UserControl.Resources>
<ObjectDataProvider
x:Key="memberStatusesDataProvider"
ObjectType="{x:Type system:Enum}"
MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="model:MemberStatus" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources>
...
<ComboBox
ItemsSource="{Binding Source={StaticResource memberStatusesDataProvider}}"
SelectedItem="{Binding Path=Status}" />
...
这会导致组合框的选项与枚举中定义的值完全相同。虽然这是我最初的目标,但我想为用户提供更好的演示,如下所示:
此外,如果应用程序中的语言发生变化,我需要使用该语言的枚举值。为了解决这个问题,我想到的第一件事是为MemberStatus
枚举值创建一个转换器。我在这个主题上发现了这篇美丽的文章:http://www.codeproject.com/KB/WPF/FriendlyEnums.aspx但MVVM模式表明根本不应该创建它们 - 我同意这一点。但是,在这个例子中,这种肯定对我没有用。
应该如何完成?谢谢。
答案 0 :(得分:3)
MVVM使价值转换器过时的观点似乎来自Josh Smith,他在博客The Philosophies of MVVM中说:
... ViewModel类本质上是一个 因此,对类固醇的价值转换器 渲染IValueConverter 界面与大多数人无关 绑定。
我从中获取(并且我同意他的价值)是视图模型负责从模型的世界视图到视图的所有转换,使转换器过时。
在模型中暴露到UI的枚举(这是一种非常以数据为中心的数据类型)绝对是一种气味 - 如果只是因为你看到的原因,向用户显示不太理想的信息。
在视图模型中放置从枚举到UI字符串的映射。
答案 1 :(得分:3)
转换器的用途不仅仅是转换enum
。转换器也比一次性viewmodel
更强可重复使用。
我可能想要将bool
转换为Brush
,我可以在视图中指定所有参数。
或者我想将string
转换为DateTime
,然后通过数据绑定将其全部转换回来。也许我想将所有内容转换为大写。然后是我最喜欢的 BoolToVisibilityConverter 。
我不想在我的VM
中提供明确的直接或间接代码,只是为了让一些少数群体感到满意。我认为他们忘记的事情是可以从Expression Blend轻松访问转换器。
转换器是WPF的重要组成部分,并且是view
和viewmodel
之间的补充。
我认为没有理由不能将它们用于enum
s。
答案 2 :(得分:2)
对于WPF的哪些部分是不允许的,MVVM并不是一成不变的。如果转换器轻松实现目标,则可以使用转换器。我甚至建议更进一步,使MarkupExtension
提供枚举值及其字符串等价物。您可以在每个枚举值的DescriptionAttribute
中存储字符串。
答案 3 :(得分:2)
我不同意MVVM确实使ValueConverters过时了。在ViewModel类中实现转换时,实现ValueConverter更有意义。
您可能对WPF Application Framework (WAF)的 BookLibrary 示例应用感兴趣。它显示了如何在MVVM应用程序中本地化枚举。请查看BookLibrary.Presentation / Converters / LanguageToStringConverter类。