简体   繁体   English

WPF MVVM代码背后

[英]WPF MVVM Code Behind

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. 我还有一些其他的代码,当用户在键盘上向左或向右按​​下时,它会向用户界面做一些事情(他们只对视图进行更改,而不是对模型或视图模型进行更改)再次我认为最好的地方因为这些是在视图背后的代码中。

So I'm asking if the code only affects the view (eg 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. 想知道这里的最佳做法是什么,或者是否有其他人有更好的建议在哪里放置此代码。

So I'm asking if the code only affects the view (eg 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不是为了让你在ViewModels中编写成千上万条丑陋的代码行,而是为了使代码可测试并引入关注点分离

If it's purely related to the view (your "focus" example is a perfect example), then just write it in the code behind. 如果它与视图完全相关(您的“焦点”示例是一个完美的示例),那么只需将其写入后面的代码中即可。

If the behavior is UI related only, then you should not put it in the ViewModel. 如果行为仅与UI相关,则不应将其放在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. 这样,您可以在尽可能多的视图中重用控件,您的视图可以避免代码隐藏,如果您优化控制,优化就会全面发生。

EDIT: 编辑:

In light of Ravi's answer, Behaviors are also a way to introduce UI related logic while leaving the View free of codebehind. 根据Ravi的回答,Behaviors也是一种引入UI相关逻辑的方法,同时让View免于代码隐藏。 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. 但是,如果您发现自己反复声明具有相同行为的相同控件,我认为最好创建一个包含该行为的控件。

That being said, if said UI logic is going to appear only once in one view, you may consider putting it in codebehind. 话虽如此,如果所述UI逻辑在一个视图中只出现一次,您可以考虑将其置于代码隐藏中。 Although it is quite rare to know in advance that you are not going to need that logic elsewhere. 虽然很少提前知道你不会在其他地方需要那种逻辑。

EDIT: 编辑:

I think @ken2k 's use of strong encouragement refers to not putting it in the ViewModel, which I also advocate. 我认为@ ken2k使用强烈的鼓励是指不把它放在我也提倡的ViewModel中。 UI logic should be implemented in the View, as he says. 正如他所说,UI逻辑应该在View中实现。 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. 第二种是将这种逻辑编码为行为,这是封装UI代码的好方法。 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. 但是,您可以找到(正如我在许多项目中所做的那样),您已经开始使用行为标签为XAML中的每个TextBox添加胡椒。 If that starts to happen, I would (and have) create a 'HighlightedTextBox' control and use that in my XAML. 如果这种情况开始发生,我会(并且已经)创建一个'HighlightedTextBox'控件并在我的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并不矛盾,但它是解决在为View放置逻辑时可能遇到的一些问题的指针。

使用自定义控件作为@Boluc Papuccuoglu建议,是不错的选择,但在使用之前我想让你看看这里的行为在WPF介绍

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内容,而不是污染ViewModel

ViewModel responsibility is to contain only data part which can be unit tested . ViewModel职责是仅包含可以进行单元测试的数据部分 With UI stuff in ViewModel, you will make it hard to be unit tested . 使用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:Class attribute at root element and other half in form of code behind. 一半是通过根元素的x:Class属性声明的,另一半是以后面的代码形式声明的。 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. 所以,按照我的说法,所有的UI内容应该放在一个地方,你不应该在将视图内容放在代码中之后再三思而后行。 (that's what it is meant for). (这就是它的意思)。 MVVM never meant design without any code behind. MVVM从未意味着没有任何代码背后的设计。

Also ViewModel responsibility is to just provide data to your view via data binding. 此外,ViewModel的职责是通过数据绑定向您的视图提供数据。 It should never be aware of UI stuff. 它永远不应该知道UI的东西。

Read more about it here - Code behind and XAML in WPF . 在这里阅读更多相关信息 - WPF中的代码隐藏和XAML

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. 即使您不想进行单元测试(或者因为您公司的bean计数器不会给您时间/预算而这样做),然后将该功能放在附加行为中意味着它们可以在其他地方使用。 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. 我不像这个网站上的其他人那样是硬核MVVM纯粹主义者,但我可以诚实地说,即使在我工作过的最大的企业应用程序中,我也从未见过绝对需要WPF代码隐藏的情况。 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM