I want to know why we should use MVVM to implement Silverlight app. What're it's advantages?
We don't do Unit Test for ViewModel, so I want other reasons.
Below are my questions about some advantages people usually say:
1.Loosely Coupled : When we use MVVM , a view rely on ViewModel but not a view, why it's loosely coupled?
2.If I provide public methods in a code-behind, they can also provide reusability.
Well, the unit-testability of the view-model is a significant advantage, so you'll miss out on that benefit. Regarding the other two:
Loosely coupled
Yes, the view does rely on the view-model. They have to be connected in some way to accomplish the function of the application. As a result, they cannot be uncoupled. The only choices are tightly-coupled or loosely-coupled or somewhere in between. With MVVM your view-model interacts with your view in a very limited way: basically just objects, properties and commands. Compare this to doing everything in the code-behind where the view and its control are essentially inseparable.
Re-use
If any code in your code-behind is re-usable enough to merit being public, it can be taken out of the code-behind and put into a general-purpose class. The problem is that what's left after that is not reusable.
If you don't want to go into the MVVM deep dive, then you can get some of the benefits of MVVM by focusing on databinding. After you learn the benefits of databinding, you can reconsider the other benefits of MVVM.
We don't do Unit Test for ViewModel,
With MVVM, it isn't just about unit testing ViewModel. Ideally, your VM should be very thin and only have properties needed by view. So, it isn't really necessary to test the VM.
But, without a VM, how do you do your your feature/functional testing across layers? In Silverlight, to facilitate testing you should use commands, instead of writing code in code-behind files. This allows you to simulate button click and other GUI events while unit testing. Using MVVM pattern along with commands, you can test all of C# code (not xaml), right up to UI (Converter, VMs, etc).
If I provide public methods in a
code-behind, they can also provide
reusability.
Not going into details of how that is a bad design, I want to ask you, How does that provide reusablity? If you create a user control, then the code-behind class is a control? You want to create instances of your control and use them? This is like saying that why do we need member methods, we can just create public static methods and access them. I have a strong opinion that if we don't want to use the automatic binding provided by WPF/Silverlight, then it is better NOT to use these technologies. And to exploit the full capabilities of binding, MVVM is essential.
why it's loosely coupled?
VM is very much part of your view. It is not decoupled from the view. As I have said, your VM should be as thin as possible with only public properties needed by your view. Your business logic will be decoupled from your view (and VM).
I think this is one of the best resources available, in case you want to use and contrast the usage of MVVM vs. ANY other pattern or no pattern.
http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/
I can answer how I use MVVM pattern.
MVVM is better in the following scenarios:
1 If several controls are bound with a single property.
MVVM:
<TextBlock x:Name="text1" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>
<TextBlock x:Name="text2" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>
I can quickly add a similar control or remove an existing control.
Compare with code-behind:
public string IsSomePropertyTrue
{
set
{
//...
text1.Visibility = value;
text2.Visibility = value;
}
}
2 Instead of a multi-converter
public Brush StateColor
{
get
{
if (this.State == State.Edited && this.IsPriority)
return new SolidColorBrush(Color.FromArgb(255, 0, 255, 0));
//...
}
}
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="{Binding StateColor}" Text="{Binding State}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
3 As an item model in controls like ListBox or DataGrid. For example, if I want to create a list of items with a remove button near each item, I will create a ItemView control and a ItemViewModel class.
<ItemsControl ItemsSource="{Binding SomeItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<view:ItemView DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
4 Copying a data from one view to another:
public JournalEntryViewModel(SalesOrderViewModel vm) {}
5 ViewModel can inherit CLR-classes and implement interfaces (INotifyPropertyChanged or INotifyDataErrorInfo).
Also I use MVVM for replacing events with commands or properties. And use of ViewModels forces to call properties by intelligible names.
I was an early adopter for WPF and I can tell you what made me choose MVVM (and this more or less applies to Silverlight as well). For the project I was working on, I had to create a screen that allowed users to subscribe to notifications within the system. This was a 3 step process:
The user had to search for the item they wanted to be notified about
They had to select the item and fill out additional options regarding the subscription
The system had to provide a summary and allow the user to confirm or edit the subscription.
After implementing the functionality the first time (without MVVM), I was told that we need to exclude from the search items that were already subscribed to by the user.
After making that fix, I was informed that we needed to give the user a live preview of the subscription based on options.
By then I started noticing that some of these changes could be extracted and made easier if I didn't have to deal with manipulating the UI as I changed the logic. I had never intentionally followed MVVM but I realized that the abstraction that I made closely matched the MVVM pattern.
So this is why I recommend the pattern. It simplifies the task of changing the logic that drives the UI by separating it from the UI itself. I also would recommend that you hold off implementing it until you need it. There is a cost to using MVVM but it is amortized over the cost of changing the UI logic.
Without MVVM, your Silverlight app code very soon will turn into unmanageable mess
What is also interesting in MVVM is dynamic automatic binding.
Imagine, that your view model has properties like this: bool IsFirstNameVisible, bool IsFirstNameEnabled, string FirstName, double FirstNameWidth etc.
In your XAML file, you define TextBox with x:Name = "FirstName" and call your dynamic MVVM-binder. It inspects your view model class via reflection, looks what properties you have defined and binds them dynamically to similar properties of control with the same name, applying value converters if needed.
In this case, your get very clean XAML, without kilometer-long data-binding expressions and converters.
That is what my MVVM library does.
Separation of Conerns people. Separation of Concerns.
Forget unit testing (I love it; but that's not the thing here). Forget reusability (do you really re-use view models? No, let's be real here).
It's about Separation of Concerns and putting code and logic where it belongs. The whole idea is maintainability; being able to make changes to the code as it evolves over time without breaking other stuff and without turning the whole thing into a big pile of spaghetti.
MVVM, done properly, allows your code to be separated into logical portions that make sense and allow for reasy refactoring and change as the app's requirements change. It's easier to find where something is when you need to make a change. Trying writing any halfway complex application and then leaving it alone for a month, then coming back to it and trying to make significant changes. A properly structured application with judicious use of MVVM is way easier to grok after a layoff, and it's way easier to make changes.
Related
Is it generally desirable to implement INotifyPropertyChanged on Model classes, ViewModel classes, or both? Is it possible to implement on Model only ,not on Viewmodel? If not possible model then why
Basic rule is - There is no hard and fast of any architecture, you can modify things to suit your needs that's why some architectures are more desirable.
for your exact needs go through this
and in this discussion, there are enough points to cover both arguments, see which one matches your project..
this might help you to implement..
You must understand the meaning of INotifyPropertyChanged. It's purpose is to raise notification from target to source when you define Binding in WPF. DependencyProperty and INotifyPropertyChanged are related for autoupdation for the concept of binding. If you need to bind the property on a viewmodel to view you have to implement a notification mechanism to notify to UI if there is change in Viewmodel. Same rule is applied for model to View.
Suppose you want to code in .CS file like Viewmodel.Name =" my new name" and expect that TextBox should display the changed name.
<TextBox Text="{Binding ViewModel.Name} "/>
Here view model need to implement INotifyPropertyChanged.
<TextBox Text="{Binding Model.Name} "/>
here model need to implement INotifyPropertyChanged
Hope it clarifies.
It might be worth noting in this discussion that Microsoft themselves add INPC in their own models e.g. the classes automatically generated when you susbscribe to a web service. I've seen it various other places as well, including a vague recollection of it somewhere in their EF stuff. I myself add it automatically to my DAL entities using Castle Proxy so that I don't have to duplicate everything in the view model, although you can also use things like Fody etc to add it to the IL in a post-processing step.
I need a reference to a Visual (one element of a XAML View Window) in my ViewModel to work with VisualTreeHelper methods like VisualTreeHelper.GetDescendantBounds(Visual reference) but I do not want to break MVVM rules and just name the viewport3d and provide it as a reference when instancing my ViewModel.
Currently I am binding the geometry as content like this to my ViewModel:
<Viewport3D>
<ModelVisual3D Content="{Binding SceneContent.Content}"/>
</Viewport3D>
But I do not see the MVVM possibility to get the containing ModelVisual3D into my ViewModel. Is there a standard (may be data-binding) approach to this in MVVM applications?
Using MVVM, we don't 'get view elements'. If you need to do something with a UI element, then that has nothing to do with MVVM. If you need to use the VisualTreeHelper.GetDescendantBounds method, then once again, that has absolutely nothing to do with MVVM... why do so many people claim to use MVVM, but know nothing about it?
Therefore, your question is invalid. It is entirely appropriate in situations like these for you to use the code behind. In fact, this is a perfect example of when we should use the code behind when following the MVVM methodology. If it is only UI related, then it has no purpose being in a view model, so simply don't put it there.
Please read the answer to the What are MVVM limitations? question to get some further insight into MVVM.
I was looking for best approach to set data context property. I found three ways
Assign data context on View (either on XAML or code behind).
Assign data context on ViewModel through constructor.
Use some configuration that takes view and view model reference and bind data context on run time through some infrastructure classes.
Which is the best option among this in terms of loosely coupled, maintainable? Or Is there any best approach?
I personally like this approach because it makes me have to write less code :). It basically uses an IValueConverter to lookup which view to use whenever a wpf control needs to present a ViewModel visually and the IValueConverter sets the datacontext for you. It also shows you how to create a datatemplate that allows you to require WPF to utilize this converter by default, something like this:
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}">
<ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>
the 4. way would be a DataTemplate.
i think the best approach is the one which fits best in your current situation.
if i have viewmodel first dynamic scenarios i use datatemplate/contentpresenter or with view first i take your way one and so on...
I'm starting to use Binding in my WPF project and I'm actually confused about few things on the presentation side (XAML).
So I want to populate a TreeView with a List of Categories. I know how to write the right HierarchicalDataTemplate for my List of Category instances.
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildrenCategories}" DataType="{x:Type src:Category}">
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</HierarchicalDataTemplate>
But what now I don't know is from where to get the list. I have here 2 solutions :
I got a Library Singleton class
which return me the right
arborescence, then I need to use an
ObjectDataProvider in my xaml which
would call the
Library.Instance.Categories method. (Which means that the controller has to be completely separated from the UI).
I got a Property ListCategories
in my page interactionLogic
(OpenUnit.xaml.cs), and bind the
tree with it.
I'm not sure about the purpose of the xaml.cs files, what are they made for? Is it normally used to store the properties (and act as a controller) or simply to have a back-end for the UI (for example get values from the UI?)?
In case the xaml.cs file is used as a controller, how do I bind my data to it, I've tried many solutions without success,my only success was with the use of static binding.
I would appreciate any comment or recommandation about UI and Logic Binding in WPF, hopefully I will get less confused.
Thanks in advance,
Boris
After reading this great article, I got a little bit less confused :
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
The article is about the Model View ViewController pattern, and how WPF integrates it. So it seems that xaml.cs files should be used as the ViewController here, and should hold the properties.
It actually make sense since it's not a good practice to mix the View and the Data, we want the designers should have a completely independant work to do.
Also for the solution 2) it is possible if you set the data context to the current file.
I was talking to someone today about picking a design pattern for how to handle logic in their WPF program and hoping that the SO community can help with further advice to make the decision easier. What factors in favour of commands outweigh the inconvenience?
I prepared a full sample along with some UML diagrams of the first two of three approaches:
Use Click event handlers on buttons and menus.
Use commands bound in XAML.
Use commands bound in code, with the XAML kept for pure GUI layout and styling.
The introductory course he'd been on and many of the books show simple Click event handlers as the natural way to connect logic to UI objects.
He was a bit stunned by the amount of overhead required to use commands with both the command being created in the code behind file:
public static readonly ICommand cmdShow2 = new RoutedUICommand(
"Show Window2", "cmdShow2",
typeof(TestDespatchWindow));
and then even more code in the XAML with the wordy way the command has to be identified and bound:
<Window x:Class="WPFDispatchDemo.TestDespatchWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:WPFDispatchDemo"..>
<Window.CommandBindings>
<CommandBinding Command="{x:Static w:TestDespatchWindow.cmdShow2}"
Executed="OnShow2" />
</Window.CommandBindings>
<DockPanel>
<StackPanel Margin="0,8,0,0">
<Button x:Name="Show2EventBased"
Margin="10,2,10,2"
Click="OnShow2"
Content="Show2 via WPF Event"/>
<Button x:Name="Show2Command"
Command="{x:Static w:TestDespatchWindow.cmdShow2}"
Margin="10,2,10,2"
Content="Show2 via WPF"/>
</StackPanel>
</DockPanel>
</Window>
I can't (yet) claim to be a WPF expert so I may have painted things as more complex than they really are but my suspicion is that you can't simplify things much more than the above.
Edit:
I found an interesting 3-way comparison between DelegateCommand, RoutedCommand and Event.
Commands their advantages and disadvantages, you have to choose based on your situation,
I highly recommend you make that choice on a case basis, don't choose "the one true way" for the entire project.
For some cases the separation between sender and receiver and the ability to send commands using only XAML is a big advantage (for a good example look how the ScrollBar control template communicates with the control logic at http://msdn.microsoft.com/en-us/library/ms742173.aspx ).
In other cases commands can turn what would have been a 2 lines event handler into some impossible to follow monstrosity involving changing 4 separate places in the application (How should the ViewModel close the form? ).
The only reason is to have well know registry of commands. Means that events are likely to be private methods and I feel that they are tightly bonded to code of the window. At the same time Commands gives ability to keep implementation (event) and definition (Command) separately, you can even use another class (take a look on ApplicationCommands).
In addition, when I am doing my WPF work I use implementation of the ICommand(Command Pattern). All logic of the command goes to the Execute method. This helps me to keep separation of logic in more structured way witout overcomplication of the window code. With this option you can create commands on your model and therefore bind them witout noise. Take a look.
Create model.
public class Model
{
ICommand CloseMessagePopupCommand {get; set;}
}
Then assign Data Context
public MainWindow()
{
this.DataContext = new Model();
}
And use follwing XAML code.
<Button
Command="{Binding CloseMessagePopupCommand}"
Content="{StaticResource Misc.Ok}" />
I try to stay true to the command pattern that Mike refers to when developing WPF applications, using a combination of Andy's #2 and #3 approaches.
I can think of only one downside of commands in my view: only certain actions of certain UI elements invoke commands. One way to get around this is to have your event handler call the Execute method on a command. I think that commands provide a very good way to encapsulate execution logic. If you maintain a large piece of UI and implement it using a MVC/MVC/MVVM pattern, this becomes very apparent.
I encourage you to take a look at Dan Crevier's series on the DataModel-View-ViewModel pattern, in particular the section on Commands and Encapsulating Commands. Even if this pattern doesn't meet your needs, it gives a great overview of how you can encapsulate logic inside a separate class.
Other variations on ICommand seem to be a popular way to implement complex command structures.
Brian Noyes in his article on PRISM says
Routed commands in WPF are very powerful and useful, but they have some shortcomings when applied to a composite application. The first is that they are entirely coupled to the visual tree-the invoker has to be part of the visual tree, and the command binding has to be tied in through the visual tree. ... The second shortcoming is that they are tightly tied in with the focus tree of the UI and goes on to talk about the DelegateCommand and CompositeCommand which CAL (Prism) includes.