I try to avoid code behind in views, within my WPF MVVM project.
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 (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.
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.
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. 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. 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. 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. 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.
Using Custom controls as #Boluc Papuccuoglu suggested, is good option but before using that i want you to take look here Behaviors in WPF introduction
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.
ViewModel responsibility 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.
As per link here at MSDN, definition of code behind:
Code-behind is a term used to describe the code that is joined with
markup-defined objects, when a XAML page is markup-compiled.
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. 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.
Also ViewModel responsibility is to just provide data to your view via data binding. It should never be aware of UI stuff.
Read more about it here - Code behind and XAML in WPF.
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.
Related
I have a WPF application implemented using MVVM. But for some small operations, such as scroll, confirmation box button click, left click operation, right click operation, etc, I am using click events directly in views.
I know MVVM does not recommend this, but is it ok to have such click events or its a bad coding practice while using MVVM? What are pros and cons of using this?
the MVVM pattern gives you:
Seperation of concerns (which is true for all UI patterns)
Unit testing of view logic, by executing the view-model without the view.
Developer-Designer workflow, allowing designers using Blend to work on the same code.
If handling UI events in code behind doesn't prohibit the above, then there is no problem. Personally I use commands if I can, but am not concerned if there is a little code-behind required.
Events can be used, but the problem with allowing codebehind events is that it's a slippery slope. you add one thing, then you add another, and all of a sudden you create actual logic in the codebehind class. (It's even more prominent if you are working with other less experienced programmers in your team).
That's why some programmers prefer, to almost no exceptions, to not write codebehind AT ALL.
Every code that fits the codebehind without being really application-logic code can also be written within a Behavior, which makes the architecture much more strict and simple to define.
If your button does something that is specific to your UI then yes you should use event handlers over commands.
e.g. If you have a button that scrolls a ScrollViewer control to the bottom then it would be bad practice to use an MVVM style command as your ViewModel would need knowledge and direct control of the view. For these situations the view should be self contained.
If your button needs to do something with data then you should use a command and perform the operation in the ViewModel.
I fully agree with #Noam M. Just to extend his answer:
Whether it's violation of MVVM or not depends on what you acually do in eventhandlers. If it's logic that is covered by the view responsibility, it's perfectly ok.
For example, PasswordBox password property cannot be databound, because it is not DependencyProperty and using PasswordChanged eventhander to set viewmodel property is perfectly ok. However, if you wrote password validation against server, that would be violation of mvvm.
I often use Loaded/Unloaded events to call Activate/Deactivate methods on my VM. When I use it too often I create behavior implemented as attached property, that does it for me, so I don't have to repeat the same code in code behind multiple times
I often use DataGrid's events in codebehind, like sorting etc.
I use TextBox.GotFocus event to select all text. Again, I create behavior when I need to reuse it.
I use codebehind to trigger, or create animations if it would be too complicated in xaml. In that case I just leave comment in xaml for other developers.
In MVVM application not all assets must be strictly written using MVVM. For example I have just written my ModalDialogWindow, where I inject content and buttons. I don't have viewmodel for this control and I do everything from codebehind. However, my application has solid MVVM architecture and I show modal dialogs from my page viewmodels using IDialogService. The ModalDialogWindow does not break testability, blendability, or readbility of my application, because in test I mock the IDialogService anyway and I don't need to test ModalDialogWindow UI itself.
Are there any disadvantages in using a private accessor to test a piece of code?
I'm weighing the option of using a private accessor only to test my GUI, as opposed the the methods/properties that are publically exposed.
This will allow some GUI testing i need, i just wanted to make sure their were not any hidden "pitfalls" in using a private accessor in how it behaves.
So to recap, your stated goal is:
I'm weighing the option of using a private accessor only to test my GUI... This will allow some GUI testing i need...
In short, yes there are pitfalls. The code you are testing is still tightly coupled to the user interface.
In the comments you clarify your goal/problem as:
What about in the case if i want to test, Drag/drop. Custom Controls, Overriden events?
All I can say is welcome aboard. The software industry has struggled with this for nearly half a century. The fact remains that testing UI is hard, Really HARD. Yes you can take a piece of code that is tightly coupled with a UI element and try and automate it; however, your going to be fighting tooth-and-nail to make headway against poor assumptions.
The 'trick' to testable UI is not to make your UI testable, but to remove the code you want to test from the UI. Thus the wide acceptance of N-Tier application development and presentation design patterns like MVC, MVVM, etc.
see the following:
Model View Controller
Model View ViewModel
Model–view–adapter
Model–view–presenter
The primary goal or driving force behind many of these design patterns is to remove the tight coupling between behavior and presentation. This enables you to then test a behavior like drag-n-drop without a user interface. My recommendation is review the patterns, choose one you like, and then start refactoring the code as you write your unit tests.
Another way to think of writing UI for testing is to remove every if, else, for, while, switch, or other control statement from your user interface code. The resulting 'shell' of a UI should be very resilient to change. Just be careful when using things like data binding that rely on reflection (which is generally an acceptable practice). The primary downside to this is that the compiler can not tell you that a member no longer exists.
Updated
#timmy you wrote:
... for example if i want to test mouse click behavior...
So what about the mouse click behavior cannot be moved to a controller rather than being embedded into the form? I guess the "Close" button might have a problem, but beyond that why not move the logic to another class that can then be tested?
BTW, You don't have to pick just one pattern MVC, MVVM, etc, they are 'guidelines' or 'suggestions' not hard rules so don't get ridiculous with it. Just try and make the logic separate from the UI and independently testable. As an example, perhaps your "Click" event fits better with a simple command class? Using a command pattern is easy, new up an object and execute it. Consider this example code for a folder copy form:
private void OnCopyClick(object sender, EventArgs args)
{
var cmd = new MyCopyCommand(this.FolderPath, this.txtTargetFolderPath.Text);
new ErrorHandler(this).Perform(cmd);
}
This works well, it has no 'real' logic other than what to provide the command and has no conditional code paths. Notice we don't even directly invoke the command but rather defer that to someone who can handle an error appropriately. Usually this 'ErrorHandler' would be provided to the Form rather than constructed directly, but you get the idea.
From this we should be easily able to verify the correct behavior of the MyCopyCommand. In the end you should wind up with a bunch of "flat functions" in the UI, ie. functions that have no nesting or curly braces. Of course this is a rule of thumb, not to be taken to such an extreme as to prevent you from being productive.
I know this may seem like a lot of work, but truthfully it is not when you are already working to write a set of tests. You can be productive AND write solid code. You just need to know when to cheat, and when not to. That comes with experience and after 20 years, 10 of those writing NUnits, I still fail once in a while. When something breaks because you didn't do this, first extract the logic from the UI, then write a unit test to prove it's broken, then fix it.
It's better not to use them, instead try to find out if you can inject any dependency. Unless you're working on a legacy code where you want to create some unit tests using private accessors, I'd suggest not to use them and even in this case, I'd recommend you do that temporarily until you refactor legacy code.
In addition to what AD.NET said.
I could use those private properties in tests only until I finish my refactoring (to Model View Controller, Model View Presenter, Model View ViewModel) so that I don't have to test GUI at all!
Is there a way in WPF for the events (such as Click) to have the method in a different .cs file rather than the MainWindow.xaml.cs (for instance)? In other words, when i go to select the mouse down event and double click on it to write the method - the method appears in MainWindow.xaml.cs .. is there a way to redirect this to another file? I would need access to all of the attributes/fields that i use (such as textboxes, buttons etc) that are on the MainWindow.....
In my MainWindow.xaml, I' have methods dealing with gotFocus and lostFocus etc. I don't want to be dealing with sockets and connection within the same file (as I feel that is bad design). Correct me if I'm wrong.
If you really wanted to, you could create a Partial Class
to put your event handlers in. It will still be part of the MainWindow class, but it will be in a different file.
That said, a better design would be to move your code for dealing with sockets and connections out into its own class or classes, while leaving the event handling code in MainWindow.xaml.cs. Partial classes aren't really the right tool to use in this case, IMO.
it sounds like what you want to do is use a MVVM design pattern (WPF lends itself very nicely to this, BTW).
here is a good article on MSDN,here is one by Josh Smith, and a google will reveal much more
it sounds like you need to look into commanding as well
If your notion is to remove the dependency between the UI and Codebehind then probably the best idea, since you are using WPF is MVVM pattern. So you that your view doesn't have to know about what is happening when you click on the button etc. Or else you can event think about ICommand to separate the commanding from your code behind. exactly something like #Mead'Dib has recommended.
The other area which you can explore is to think about something like Command Pattern where you can separate the Receiver and invoker. So that you are not tightly coupled with the code behind. So just think about using some kind of pattern that will make you safe when maintenance issues there.
Recently i got explained that MVVM can only be done "the right way" if i use DataTemplates. Is this truely the case?
I'd say its a good idea to use DataTemplates if you want highly reusable "Views".
But if i am going to develop an application that has, say, five to ten different pages, and there is very little to none reuse of specific controls (like the "Person" view is only used once, and its highly likely that this requirement doenst change), why cant i simply create a usercontrol and put that directly into the code?
Am i missing some important core principle of MVVM here?
Main selling point of MVVM is separation of View from the ViewModel (so that VM doesnt know about View) by using powerful Binding feature of WPF.
DataTemplates are a just another feature which allows you to represent data in different way. As you have said, if you dont have reusable DataTemplate then dont create one, even if you do make sure it resides in the View's Resources, you can share it wider group if you wanted do.
using UserControl can be useful where you need to do something extra (apart from simple representing data), for example, some complex validation or extra commands/buttons
I dont think MVVM and DataTemplates are related in the same context.
There is no special needing for DataTemplate, you have a view and a viewmodel that cooperates with databindings and events. The MVVM goal in WPF is to remove the code from the view to achieve a real presentation only view, and not a messy code behind store. Having the ViewModel agnostic from the view is another goal, even if not always achieved.
The more I learn about WPF and XAML, the more I realize that you can do pretty much all of your GUI initialization and event handling glue in either XAML or in code (say C# code or VB.Net code).
My question is to those who have been working on WPF for longer and ideally those who have shipped apps with it -- where did you find was the best place to 'draw the line' between XAML and code? Did you use XAML wherever you could? Only where interfacing with non-coding UI designers?
Any tips in this area would be extremely helpful to myself and other coders who are just getting into WPF programming and are kind of paralyzed by all the choices we can make!
One thing that I would look at is the model-view-view model pattern. It is a very elegant pattern which naturally separates everything into nice buckets ... including your xaml.
For example, it helps you keep a clear boundary between the developer and the designer and even allows for test driven development.
There is a whole bunch of info out there on it, but I would start with John Gossman's blog posts:
http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx
http://blogs.msdn.com/johngossman/archive/2005/10/09/478894.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/26/539598.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/27/540304.aspx
http://blogs.msdn.com/johngossman/archive/2006/03/04/543695.aspx
http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx
Update:
Just want to point people to another StackOverflow post with lots of good info on M-V-VM in it.
One tip is to not declare event handlers in XAML. Instead, name your elements and attach events handlers in the code-behind. That helps keep a clean separation between the designer and developer.
As others have suggested, try following the Model-View-ViewModel pattern. However, it's OK to put stuff in the codebehind! The rule is that if it's "View" related, you put it in the Xaml or the codebehind (whichever is more convenient for you). If it's more business logic related to how the user interacts with the system, then it belongs in the ViewModel. If it's just business logic not concerned with interaction, it belongs in the Model.
Examples of each would be:
Model: defines a property called ModifiedDate that stores the last time it was modified.
ViewModel: converts the ModifiedDate into an enumeration property called ModifiedAge, based on when it was modified: Yesterday, In the Last Week, In the Last Month, In the Last Year, etc.
View: converts the ModifiedAge property to a background color where more recently accessed data is highlighted bright yellow, and less recently accessed data is more of a beige-khaki-gray that your designer insists is called "Meadow Lark Lilly Flowerpot".
Another tip is to separate XAML into functional and aesthetic. Developers would typically work in the functional XAML whilst designers care primarily about the aesthetic. This keeps the functional XAML very easy to grok, which is important because developers often need to edit such XAML. Aesthetic XAML is typically edited by designers using tools, so its neatness and verbosity is less of an issue.
I did a bit of a blog post on this a while ago here.
Don't lose sight of the fact that XAML is code. It's declarative and all that, but it's still a programming language. In fact, it goes through a conversion to C# or Visual Basic before it's turned into IL for the .NET compiler to chew on.
I'll echo Scott Whitlock's comment: MVVM is a great way to separate concerns and focus on architectural details. It's really, really OK to put stuff in your code-behind, especially the stuff he describes. If you don't have a requirement to separate designer from developer, then adapt the MVVM pattern to your specific needs; don't try to force yourself to be pure or idealistic about it.
It's also perfectly OK to put calls to your ViewModel's methods right in the View code behind, if you don't need the flexibility of commanding with ICommand classes. Or if you know the View you're making will always be bound to the ViewModel class you're making. Or you could take things a step further, define an interface for your ViewModel, and bind only to implementations of that interface. Then you can still swap out the ViewModel whenever you want.
Stuff like that.
When you follow a proper pattern like Mode-View-ViewModel you will get opportunity to do more on XAML side and less on code behind. Maximize the usage of RoutedEvents and Commands in WPF code.
When building UserControls I try to Xamlize as much as possible.
One tip I found in the field is that creating ControlTemplate and DataTemplates by hand is really a pain in the ***... I always write those in XAML....
I would say use as much xaml possible, using Binding, commands, styles, templates etc. I had to support functionality of saving and loading templates using XAMLReader/XAMLWriter and it more easier for controls having more xaml.