WPF:MVVM 对转换器说不,但我需要好的枚举值
在模型层中,我定义了一个枚举:
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 模式表明几乎根本不需要创建它们 - 我同意这一点。然而,在这个例子中,这种肯定对我来说并不有利。
应该怎样做呢?谢谢。
In the model tier, I have defined an enum:
public enum MemberStatus
{
ActiveMember = 0,
InactiveMember = 1,
Associate = 2,
BoardMember = 3,
Alumni = 4
}
In my view, I have a combo box that is populated with those enum values:
<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}" />
...
This results in getting the combo box with the choices that are exactly the same as values defined in the enum. Although that was my initial goal, I want nicer presentation for the user, something like this:
- Combo box choices:
- Active member
- Inactive member
- Associate
- Member of the board
- Alumni
Also, if the language in the application changes, I need the enum values in that language. To tackle this, the first thing that came to my mind is to create a converter for MemberStatus
enum values. I found this beuatiful article on the topic: http://www.codeproject.com/KB/WPF/FriendlyEnums.aspx But MVVM pattern says that there should be no need to create them almost at all - and I agree with this. However, this affirmation does not work in my favor in this example.
How is it supposed to be done? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
MVVM 使价值转换器变得过时的观点似乎来自 Josh Smith,他在他的博客文章 MVVM 的哲学:
我从中得到的(我同意他的观点)是视图模型负责从模型的世界观到视图的所有转换,从而使转换器过时。
在暴露给 UI 的模型中使用枚举(这是一种非常以数据为中心的数据类型)绝对是一种味道 - 如果只是出于您所看到的原因,向用户显示不太理想的信息。
将枚举到 UI 字符串的映射放入视图模型中。
The view that MVVM makes value converters obsolete appears to have come from Josh Smith who says in his blog post The Philosophies of MVVM:
What I take from that (and I agree with him for what it is worth) is the the View Model is responsible for all conversion from the Model's view of the world to the Views, rendering the converter obsolete.
Having an enum (which is a very data centric data type) in the Model exposed up to the UI is definitely a smell - if only for the reason you see, of showing less than ideal information to the user.
Put a mapping from enum to UI string in your View Model.
转换器的用途远不止转换枚举。转换器也比一次性的
viewmodel
更可重用。我可能想将
bool
转换为Brush
,并且我可以在视图中指定所有参数。或者也许我想将
string
转换为DateTime
并通过数据绑定再次转换回来。也许我想将所有内容都转换为大写。然后是我最喜欢的 BoolToVisibilityConverter。我不想在我的整个
VM
中放置显式的直接或间接代码,只是为了让一些少数群体满意。我认为他们忘记的是可以从 Expression Blend 轻松访问转换器。转换器是 WPF 的重要组成部分,也是
view
和viewmodel
之间绑定的补充。我认为没有理由不能将它们用于
enum
。Converters are useful for way more than converting
enum
s. Converters are also more reusable than a one-offviewmodel
is.I might want to convert a
bool
to aBrush
and I can specify the parameters all in the view.Or maybe I want to convert a
string
toDateTime
and back again all via data binding. Maybe I want to convert everything to upper case. Then there is my favourite BoolToVisibilityConverter.I'd hate to put explicit direct or indirect code all throughout my
VM
s just to keep some minority groups happy. The thing I would argue they forget is that converters are easily accessible from Expression Blend.Converters are an essential part of WPF and suppliment binding between
view
andviewmodel
.I see no reason why you can't use them for
enum
s.对于 WPF 的哪些部分是允许的、哪些部分是不允许的,MVVM 并不是一成不变的。如果转换器可以轻松实现您的目标,那么使用它们就很好。我什至建议更进一步,创建一个
MarkupExtension
来提供枚举值及其等效字符串。您可以将字符串存储在每个枚举值的DescriptionAttribute
中。MVVM is not really set in stone as to what parts of WPF are and are-not allowed. Converters are fine to use if they accomplish your goal easily. I would even suggest taking it a step further and making a
MarkupExtension
to supply the enum values and their string equivalents. You could store the strings in aDescriptionAttribute
on each enum value.我不同意 MVVM 确实会让 ValueConverters 过时。在很多情况下,实现 ValueConverter 比在 ViewModel 类中实现转换更有意义。
您可能对 WPF 应用程序框架 (WAF) 的 BookLibrary 示例应用程序感兴趣强>。它展示了如何在 MVVM 应用程序中本地化枚举。请查看 BookLibrary.Presentation / Converters / LanguageToStringConverter 类。
I don’t agree that MVVM does make ValueConverters obsolete. There are more than enough scenarios where implementing a ValueConverter makes more sense as implementing the conversion in the ViewModel class.
You might be interested in the BookLibrary sample application of the WPF Application Framework (WAF). It shows how an enum can be localized in a MVVM application. Please have a look at the BookLibrary.Presentation / Converters / LanguageToStringConverter class.