我尝试在我的WPF MVVM项目中避免代码隐藏在视图中。
但是我有一些非常具体的观点。例如,当控件获得焦点时,我希望突出显示全文(即使用户单击文本框)。
在这里,我可以选择在视图模型中处理这个问题(然后需要了解视图,我想避免这种情况)。
我还有一些其他的代码,当用户在键盘上向左或向右按下时,它会向用户界面执行操作(并且他们只对视图进行更改,而不是对模型或视图模型进行更改)并且我正在考虑这些的最佳位置是视图背后的代码。
所以我问的是代码是否只影响视图(例如光标移动,选择文本框中的所有文本等等,而不是模型或视图模型,是否可以将其放入代码中落后,而不是其他地方。
想知道这里的最佳做法是什么,或者是否有其他人有更好的建议放置此代码的位置。
答案 0 :(得分:20)
所以我问的是代码是否只会影响视图(例如 光标移动,选择文本框中的所有文本等...,而不是 模型或视图模型,可以把它放在代码后面,而不是 别处。
不仅可以,而且强烈鼓励。 MVVM不是为了你在ViewModels中编写成千上万条丑陋的代码行,而是为了使代码可以测试并引入关注点分离。
如果它与视图完全相关(你的“焦点”示例是一个完美的例子),那么就把它写在后面的代码中。
答案 1 :(得分:8)
如果行为仅与UI相关,则不应将其放在ViewModel中。您给出的突出显示示例就是这种情况的一个很好的例子。话虽如此,我建议你避免重复你的代码(例如)创建一个自定义控件,当它有焦点时突出显示文本。这样,您可以在尽可能多的视图中重用控件,您的视图可以避免代码隐藏,如果您优化控制,优化就会全面发生。
修改强>
根据Ravi的回答,行为也是一种介绍UI相关逻辑的方法,同时让View免于代码隐藏。但是,如果您发现自己反复声明具有相同行为的相同控件,我认为最好创建一个包含该行为的控件。
话虽如此,如果所述UI逻辑在一个视图中只出现一次,您可以考虑将其置于代码隐藏中。虽然很少提前知道你不会在其他地方需要这种逻辑。
修改强>
我认为@ ken2k使用强烈的鼓励是指不将它放在我也提倡的ViewModel中。正如他所说,UI逻辑应该在View中实现。现在,有几种方法可以做到这一点。其中之一是直接在代码隐藏中编码,这可能导致重复的代码和维护问题。此外,如果您使用单元测试,它可能会让您陷入困境。第二种是将这种逻辑编码为行为,这是封装UI代码的好方法。然后,您可以对行为进行单元测试,以确保其正常工作。但是,您可以找到(正如我在许多项目中所做的那样),您已经开始使用行为标签为XAML中的每个TextBox添加胡椒。如果这种情况开始发生,我会(并且已经)创建一个'HighlightedTextBox'控件并在我的XAML中使用它。总之,我的建议并不与ken2k相矛盾,但它是解决在为View放置逻辑时可能遇到的一些问题的指针。
答案 2 :(得分:5)
建议使用自定义控件作为@Boluc Papuccuoglu
,这是不错的选择,但在使用之前我想让你看看Behaviors in WPF introduction
答案 3 :(得分:3)
强烈建议您将所有视图逻辑逻辑放在一个位置。 您应该始终将View内容保留在XAML和代码中,而不是污染ViewModel。
ViewModel
责任是 仅包含可以进行单元测试的数据部分 。 使用ViewModel中的UI内容,您将难以进行单元测试。
根据MSDN的链接,后面的代码定义:
代码隐藏是一个术语,用于描述与之相关的代码 当标记编译XAML页时,标记定义的对象。
正如您所看到的, 背后的代码是您视图的部分类 。一半是通过根元素的x:Class
属性声明的,另一半是代码形式的背后声明。所以,按照我的说法,所有的UI内容应该放在一个地方,你不应该在将视图内容放在代码中之前再三思。 (这就是它的意思)。 MVVM从未意味着没有任何代码的设计。
ViewModel的职责是通过数据绑定向您的视图提供数据。它永远不应该知道UI的东西。
在此处阅读更多相关信息 - Code behind and XAML in WPF。
答案 4 :(得分:-1)
您想要多少代码进行单元测试?如果您的视图可以在控件获得焦点时触发命令,并且您的视图模型可以以编程方式触发事件以突出显示该控件中的文本,那么您将拥有使用模拟对象对该行为进行单元测试所需的一切。即使您不想进行单元测试(或者因为您公司的bean计数器不会给您时间/预算而这样做),然后将该功能放在附加行为中意味着它们可以在其他地方使用。我不像这个网站上的其他人那样是硬核MVVM纯粹主义者,但我可以诚实地说,即使在我工作过的最大的企业应用程序中,我也从未见过绝对需要WPF代码隐藏的情况。