WPF MVVM 代码背后
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20883199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF MVVM Code Behind
提问by DermFrench
I try to avoid code behind in views, within my WPF MVVM project.
我尽量避免在我的 WPF MVVM 项目中的视图中隐藏代码。
However I have some things that are very specific to the view. For example when a control gets focus I want the full text to be highlighted (even if a user clicks into the text box).
但是,我有一些非常特定于该视图的内容。例如,当控件获得焦点时,我希望突出显示全文(即使用户单击文本框)。
Here I have a choice to handle this in the view model (which would then need to know about the view, which I want to avoid).
在这里,我可以选择在视图模型中处理这个问题(然后需要了解我想避免的视图)。
I also have some other code like that does things to the UI when the user presses up down left or right on the keyboard (and they only make changes to the view, not the model or viewmodel) and again I'm thinking the best place for these is in the code behind of the view.
当用户在键盘上向左或向右按下时,我还有一些其他类似的代码对 UI 执行操作(并且他们只更改视图,而不是模型或视图模型),我又在想最好的地方因为这些在视图后面的代码中。
So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.
所以我问代码是否只影响视图(例如光标移动,选择文本框中的所有文本等......而不是模型或视图模型,是否可以将其放在代码后面,而不是比别处。
Wondering what is best practise here, or if anyone else has a better suggestion where to put this code.
想知道这里的最佳实践是什么,或者是否有人有更好的建议来放置这段代码。
采纳答案by Boluc Papuccuoglu
If the behavior is UI related only, then you should not put it in the ViewModel. The highlighting example you gave is a good example of such a case. Having said that, I would suggest you avoid repeating your code by (for example) creating a custom control that highlights the text when it has the focus. This way, you can reuse the control in as many views as you can, your views stay free of codebehind, and if you optimize your control, the optimizations happen across the board.
如果行为仅与 UI 相关,则不应将其放在 ViewModel 中。你给出的突出显示的例子就是这种情况的一个很好的例子。话虽如此,我建议您通过(例如)创建一个自定义控件来避免重复您的代码,该控件在具有焦点时突出显示文本。通过这种方式,您可以在尽可能多的视图中重用控件,您的视图不会有代码隐藏,如果您优化控件,优化就会全面进行。
EDIT:
编辑:
In light of Ravi's answer, Behaviors are also a way to introduce UI related logic while leaving the View free of codebehind. However, if you are finding yourself repeatedly declaring the same controls with the same behaviors, in my opinion it is better to create a control that incorporates the behavior.
根据 Ravi 的回答,Behaviors 也是一种引入 UI 相关逻辑的方式,同时让 View 没有代码隐藏。但是,如果您发现自己反复声明具有相同行为的相同控件,在我看来,最好创建一个包含该行为的控件。
That being said, if said UI logic is going to appear only once in one view, you may consider putting it in codebehind. Although it is quite rare to know in advance that you are not going to need that logic elsewhere.
话虽如此,如果所述 UI 逻辑仅在一个视图中出现一次,您可以考虑将其放在代码隐藏中。尽管很少提前知道您在其他地方不需要该逻辑。
EDIT:
编辑:
I think @ken2k 's use of strong encouragement refers to not putting it in the ViewModel, which I also advocate. UI logic should be implemented in the View, as he says. Now, there are a few ways of doing that. One of these is coding it directly in your codebehind, which can lead to repetitious code and maintenance issues. Also, if you employ unit testing, it could put you in a difficult spot. The second is coding such logic into behaviors, which is a good way to encapsulate UI code. You can then unit test the behavior to make sure it works OK. However, you can find (as I did, in many projects) that you have started to pepper every TextBox in your XAML's with behavior tags. If that starts to happen, I would (and have) create a 'HighlightedTextBox' control and use that in my XAML. In summary, my suggestion does not contradict ken2k's, but is a pointer in the direction of resolving some issues you may have when placing logic for your View.
我认为@ken2k 的强烈鼓励是指不要把它放在ViewModel中,我也提倡。正如他所说,UI 逻辑应该在视图中实现。现在,有几种方法可以做到这一点。其中之一是直接在您的代码隐藏中对其进行编码,这可能会导致重复的代码和维护问题。此外,如果您使用单元测试,它可能会让您陷入困境。二是把这样的逻辑编码成行为,这是封装UI代码的好方法。然后,您可以对行为进行单元测试以确保其正常工作。但是,您会发现(正如我在许多项目中所做的那样)您已经开始在 XAML 中的每个 TextBox 中添加行为标签。如果这种情况开始发生,我会(并且已经)创建一个“HighlightedTextBox”控件并在我的 XAML 中使用它。总之,
回答by ken2k
So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.
所以我问代码是否只影响视图(例如光标移动,选择文本框中的所有文本等......而不是模型或视图模型,是否可以将其放在代码后面,而不是比别处。
Not only it is OK, but it is strongly encouraged. MVVM is not here for you to write thousands of ugly lines of code in ViewModels, it's here to make the code testable and to introduce a separation of concerns.
不仅可以,而且强烈建议这样做。MVVM 不是为了让您在 ViewModel 中编写数千行丑陋的代码,而是为了使代码可测试并引入关注点分离。
If it's purely related to the view (your "focus" example is a perfect example), then just write it in the code behind.
如果它纯粹与视图相关(您的“焦点”示例是一个完美的示例),那么只需将其写在后面的代码中。
回答by Ravi
Using Custom controls as @Boluc Papuccuoglusuggested, is good option but before using that i want you to take look here Behaviors in WPF introduction
按照@Boluc Papuccuoglu建议使用自定义控件是不错的选择,但在使用之前,我希望您先看一下WPF 中的行为介绍
回答by Rohit Vats
It is strongly recommended to have all your view stuff logic at one place. Instead of polluting ViewModel you should always keep View stuffs in XAML and code behind.
强烈建议将所有视图内容逻辑放在一个地方。您应该始终将 XAML 中的 View 内容和代码保留在.
ViewModelresponsibility is to contain only data part which can be unit tested. With UI stuff in ViewModel, you will make it hard to be unit tested.
ViewModel责任是只包含可以进行单元测试的数据部分。使用 ViewModel 中的 UI 内容,您将很难进行单元测试。
As per link here at MSDN, definition of code behind:
根据MSDN 上的链接,后面的代码定义:
Code-behind is a term used to describe the code that is joined with markup-defined objects, when a XAML page is markup-compiled.
代码隐藏是一个术语,用于描述在 XAML 页面经过标记编译时与标记定义的对象连接的代码。
As you can see, code behind is partial class of your view. One half is declared via x:Classattribute at root element and other half in form of code behind. So, as per me all UI stuff should be at one place and you should not think twice before placing the view stuff in code behind. (that's what it is meant for). MVVM never meant design without any code behind.
如您所见,后面的代码是您的视图的部分类。一半通过x:Class根元素的属性声明,另一半通过后面的代码形式声明。所以,在我看来,所有 UI 的东西都应该放在一个地方,在将视图的东西放在后面的代码中之前,你不应该三思而后行。(这就是它的意思)。MVVM 绝不意味着没有任何代码背后的设计。
Also ViewModel responsibility is to just provide data to your view via data binding. It should never be aware of UI stuff.
ViewModel 的职责也只是通过数据绑定向您的视图提供数据。它永远不应该知道 UI 的东西。
Read more about it here - Code behind and XAML in WPF.
在此处阅读更多相关信息 - WPF 中的代码隐藏和 XAML。
回答by Mark Feldman
How much of your code do you want to unit test? If your view can trigger a command when a control gets focus and your view model can programatically fire an event to highlight the text in that control then you have everything you need to unit test that behaviour with mocked objects. And even if you don't want to unit test (or can't because the bean-counters at your company won't give you the time/budget to do so) then placing that functionality in attached behaviours means they can be used elsewhere. I'm not quite the hard-core MVVM purist as some others on this site but I can honestly say that even in the largest enterprise applications I've worked on I've never once seen a case where WPF code-behind was absolutely required.
您要对多少代码进行单元测试?如果您的视图可以在控件获得焦点时触发命令,并且您的视图模型可以以编程方式触发事件以突出显示该控件中的文本,那么您就拥有了使用模拟对象对该行为进行单元测试所需的一切。即使您不想进行单元测试(或者不能,因为您公司的 bean-counters 不会给您这样做的时间/预算),然后将该功能放在附加行为中意味着它们可以在其他地方使用. 我不像本网站上的其他一些人那样是铁杆 MVVM 纯粹主义者,但我可以诚实地说,即使在我工作过的最大的企业应用程序中,我也从未见过绝对需要 WPF 代码隐藏的情况.

