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.
Related
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.
do you think is a good practise to create a UserControl already with a ViewModel and deploy both together? This way the UserControl will be binded to the ViewModel from stock.
Looks as a good idea to me but I never saw such a thing.
Thanks.
The one thing you should be careful of with this approach is that you want to keep your datacontext open and available for binding to in controls where you are using this control.
If you block the data context it'll make it so any bindings you do to the control later will have to have a source specified.
I personally see nothing bad in this idea. For a sufficiently complex UserControl, a ViewModel is anyway needed. I would however make it (VM) as extensible as possible.
Indeed, I've seen some VMs shipped together with controls -- in Swing (Java). For example, TableModel serves indeed as a kind of VM for JTable. [But without real bindings Swing's VMs are quite weak.]
I'm using PRISM and MVVM in my modular Silverlight application. I'm still trying to figure out PROPER way to do interactions in MVVM fashion and 2 methods that PRISM and samples offer is not something I like for different reasons.
Method 1(PRISM): To use different region adapter. Basically, it involves attached properties on container and injecting view into region. This works almost 100% but negative of this method is that there is no good way to communicate results back. I can use EventAggregator but something doesn't feel right to raise event with data when interaction completed.
Method 2(PRISM): To use InteractionRequest. That involves trigger action and some big boilerplate XAML that I have to repeat on each view.
I'm thinking on creating something on my own which would require creating my own control which will have to be added to each view but with very little XAML and some kind of IPopupService that I can bind this control to. I can pass all needed data via PopupService but in order to actually make action of POPUP happen - I need to call method on this control and that falls apart in MVVM
I wonder how to call method on control in MVVM where view shouldn't be aware of VM ?
View has no option but be aware of VM, since it binds to it.
You could define some kind of a service indeed with a run-time implementation that would interact with the UI and design/test/debug implementation that does something else. You might also publish some events in your VM layer that the View layer would decide how to interpret.
First off, I don't think MVVM is a good choice if you are developing a UserControl that will be consumed by others. A lookless control is what you really should be developing. Jeremiah Morrill has a blog post about this subject.
With that said, you can set the datacontext with XAML if you have a default public constructor.
Inside ControlView.xaml put:
<UserControl.DataContext>
<local:ControlViewModel />
</UserControl.DataContext>
I want to create two diffent types of DockPanels. If the user clicks on one link, it loads DockPanel #1 otherwise it loads #2.
Can we dynamically swap them? I'm new to WPF. In REALBasic, I'd use GroupPanels and I'd swap them if needed.
Thanks
U can dynamicly create controls and fill their content with other controls. Or u can just place both types and hide one u dont want to show.
Take a look at Josh Smith's MVVM Article in MSDN Magazine. Josh is considered by many to be The MVVM Guru, and this article does a good job at explaining the basics.
With that in mind, I would probably do your app as an MVVM application.
The Model would "just" be your data model (much like in MVC).
Next there would be a View for each of your panels. Each View could either be set up as a DataTemplate (like in the article), or as a UserControl (as I've done and seen done many other places as well). Doing so makes it modular, and easier to expand, maintain, etc.
Your MainWindow is really also considered a View, onto which you place other Views.
All of the Views will be controlled by one or more ViewModel classes. How many you have depends on your design. Generally, if there is distinct functionality, you will have a more-or-less one-to-one relationship between a View and a ViewModel (although you can certainly share multiple Views with a single ViewModel). There will also generally be a single "Main ViewModel" class to hold everything together.
In general terms given the general description of your problem, it is likely that your ViewModel will contain a Command (or Commands), handled when your user chooses a link. This Command will likely set some property, which will control which View gets shown (usually via Binding).
Sorry I can't get more detailed than this, but if I did I'd need to know more about your design, and I'd have to write a lot more stuff, which isn't really appropriate in this forum.
I'm starting to develop a WP7 app with MVVM Light. I want to make use of the pivot control to show two different lists of different item types. Would it be best practice to create the PivotItems as UserControls or should I stick everything in one viewmodel?
I think there is no "correct" way to do it, it just depends on your vision.
Personnally, I always create separate UserControls to act as PivotItems.
The main objective is to make my code clearer, with more separate classes it is way more easily unserstandable!
However it also depends on the complexity of the items. Don't feel forced to create one UserControl per item, just separate if the control is quite complex and requires quite a lot of XAML lines, it will clarify your code