声明性ui /视图层的值转换?

时间:2013-07-25 23:29:06

标签: design-patterns model-view-controller data-binding view declarative

我有一个带有简单MVC架构的应用程序(桌面,而不是web或.net),可以通过简单的绑定机制从模型中显示值和值列表。

模型是树结构标量和数组节点。一些节点是原始值,一些节点具有成员子节点。

视图级绑定语法类似于:

app_root.some_node.prices[1]  // single "price" object 
app_root.some_node.prices     // all "price" objects 

现在,我需要在通过某种转换过程运行它们之后显示这些值。

为了举例:实时货币转换。即一些比仅仅格式化更复杂的东西,可能会失败或在某种程度上依赖于应用程序状态。

如何在保持MVC系统和绑定语法合理的同时添加此功能?

我能想到的两个直接选择是:

// Fake "arguments" to a generic app-level converter node?
//
// Very hack-ish looking and now the app has a new 
// global "currency_converter" node.
//
app_root.currency_converter.euro.app_root.some_node.prices[1]
app_root.currency_converter.yen.app_root.some_node.prices[1]

// Ad-hoc extension to the "price" objects?
//
// Cleaner binding path, but now I need modify the "price" object for
// each new currency.  This also seems wrong.
//
app_root.some_node.prices[1].asEuro
app_root.some_node.prices[1].asYen // etc.

// Adding a post-fix converter option? 
//
// Still a cleaner binding path, but now there must exist some magic 
// conversion system/registry that the "As" sub-node must know how to talk to.
// 
app_root.some_node.prices[1].As.Euro
app_root.some_node.prices[1].As.Yen // etc.

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我会选择第二个选项,因为第一个选项会导致转换器膨胀,你最终会得到很多你需要管理的转换器。

我不知道您正在使用哪种平台或技术,但有时看看其他人是如何做到这一点很有帮助,我使用的是WPF,这是微软的桌面应用程序堆栈,他们有一个绑定对象可以使用格式化这样:

<Label Content={Binding Path=CurrentAmount, Format=Cost: {0:C}} />
                                            ^^^^^^^^^^^^^^^^^^

Binding是一个对象,FormatPath以外的参数之一,所以也许你可以在你的框架中实现类似的东西。

编辑:我向您展示了WPF如何执行简单格式化,但系统还具有更复杂的转换功能,并且可以采用与格式相同的方式应用。

以下是之前的相同示例,但此次添加了转换:

<Label Content={Binding Path=CurrentAmount, Format=Cost: {0:C}, Converter=myConverter />
                                                                ^^^^^^^^^^^^^^^^^^^^^

正如您所看到的,您也可以使用转换器参数,myConverter实际上是一个实现名为IValueConverter的WPF接口的类,它可以将值从视图层来回转换为模型,反之亦然。