Can somebody guide me what should be the design if I want to create a MVVM application in Prism(Silverlight) using MEF( I am not sure how to import or export ViewModel using MEF).
I saw few article which are binding ViewModel with View using DataContext(either in XAML or codebehind of View).
And I saw few guys who are having IView & IViewModel interface & both are having reference variable of each other.
And at some places the guidelines says ViewModel should never be referring to View.
It would be nice if somebody can provide me code snippet.
Have you read the Prism documentation? They have a section on Implementing the MVVM Pattern which discusses different techniques for wiring up the viewmodel and view.
You could also implement a composite application with an MVVM framework such as Caliburn.Micro which uses conventions for viewmodel/view binding.
I would bind the DataContext using setter injection in the code behind. Both the view and the view model are created by MEF.
[Import]
private MyViewModelClass ViewModel
{
get { return this.DataContext as MyViewModelClass; }
set { this.DataContext = value; }
}
Related
I am looking for a solution/mvvm framework that supports nesting ViewModels and Views. What I mean is:
Each ViewModel derives from BaseViewModel
ViewModels have properties that are of type BaseViewModel which are sub-ViewModels (nested inside parent ViewModel)
Each ViewModel have corresponding View
Views have ContentControl (control that can display templated view) corresponding to sub-ViewModels of corresponding ViewModel
Now, when creating instance of ViewModel it is needed to pass appropriate instances of concrete sub-ViewModels. Views should be automatically resolved and nested (somehow) base on ViewModels structure.
I do not define somehow because there may be a lot of ways to do it.
I hope my idea is clear. This approach allows easy and dynamic creation of ViewModels and Views. Just create tree of ViewModels, for example in XML, and base on this create new functionality.
The questions are:
Is there any mvvm framework (mvvmcross, catel) supporting such approach for Xamarin.Forms?
How would you store tree of ViewModels - in XML, database tables, ...?
How would you create instances of ViewModels - deserialization, dependency injection, ...?
How to create Views and resolve (if framework does not support it)?
After some time I can share some experience about the questions I asked:
I do not know whether there is any mvvm framework supporting such approach. Probably Catel v5 is going to support this, but I did not checked this. I use custom solution.
In my solution I store ViewModels definitions in single database table in parent/child structure.
ViewModel instances are created by custom factories using definitions from database table.
Views are created using ValueConverters. It is possible, because each view has bindings created base on ViewModels structure.
Beside above answers I can suggest to use Prism. Although it has some disadvantages for me it is the best framework in such approach.
Yes! There's an MVVM Framework that fits exactly to what you are looking for and is created with Xamarin.Forms in mind:
FreshMvvM: https://github.com/rid00z/FreshMvvm
Quickstart Guide: http://www.michaelridland.com/xamarin/freshmvvm-quick-start-guide/
How does it compare to other options?
It's super light and super simple
It's specifically designed for Xamarin.Forms
Designed to be easy to learn and develop (great when you are not ready for RxUI)
Uses a Convention over Configuration
Features
PageModel to PageModel Navigation
Automatic wiring of BindingContext
Automatic wiring of Page events (eg. appearing)
Basic methods (with values) on PageModel (init, reverseinit)
Built in IOC Container
PageModel Constructor Injection
Basic methods available in Model, like Alert
Built in Navigation types for SimpleNavigation, Tabbed and MasterDetail
You can nest or derive ViewModels as much as you'd like (In our case we have a BaseViewModel). We have been using FreshMvvM for our startup and has been battle tested to work and fit to whatever we need.
Can someone explain What benefits an MVVM framework such as ReactiveUI or MVVM Light provides to Xamarin.Forms application? we can implement INotifyPropertyChanged in our viewmodels without using any of these frameworks.
Am I missing something?
I'm an author of a small MVVM framework for Xamarin.Forms (https://github.com/daniel-luberda/DLToolkit.PageFactory). I'll try to point some advantages of using it as some of features are common for other frameworks too:
Ready to use INotifyPropertyChanged implementation (just inherit from BaseViewModel or BaseModel)
ViewModel oriented Navigation (you can move your navigation logic to view models)
Built-in messaging to easily pass data/arguments between pages or view models
Page caching and reusing (better UI experience as views/pages are reused)
Every page has access to typed ViewModel instance which is automatically instantiated and wired to BindingContext
Those features vary between libraries. Some of more advanced MVVM frameworks offer you a possibility to move your entire project to a different platforms/sdks as they have multi platform support. It may be a nice deal for a larger projects.
Sample code to illustrate some features (the code is called from a ViewModel):
PageFactory.GetPageFromCache<SecondPageModel>()
.ResetPageModel()
.SendActionToPageModel((model) => { model.Message = "Hello World!"; })
.PushPage();
There is more to an MVVM Framework than just INotifyPropertyChanged. To give just a couple of examples there are:
RelayCommand - A class that can provides an implementation of the ICommand interface and allows you to bind a delegate to the view. Useful for buttons
EventToCommand - This allows you to bind an event to a command in your view model. Instead of having to use code behind for UIElement Events
These are just two classes that are provided by an MVVM Framework such as MVVMLight
By using MVVMLight it means that you do not have to implement INotifyPropertyChanged in every project you just make sure your ViewModel inherits from ViewModelBase and you also don't have to write your own implementation in every project for the two classes mentioned above.
The final thing to mention is that you can also install code snippets for MVVMLight. Meaning that writing code is EVEN faster!
For example if you would like a property that raises property changed as well just use the mvvmlight property snippet. And similarly if you would like a RelayCommand property you can just use the mvvmlight RelayCommand snippet
The Model-View-ViewModel (MVVM) architectural pattern was invented with XAML in mind. The pattern enforces a separation of the XAML user interface (the View) from the underlying data (the Model) through a class that serves as an intermediary between the View and the Model (the ViewModel). The View and the ViewModel are often connected through data bindings defined in the XAML file. The BindingContext for the View is usually an instance of the ViewModel. Please click here to see more details and sample code.
You don't need to use ReactiveUI or MVVM Light, you can just use INotifyPropertyChanged interface to notify clients that a property value has changed.Below, you can see my ViewModelBase class code, hope this helps you out;
public class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
In my ViewModel here is how I inherit from ViewModelBase and how I create my property;
public class ImageButtonViewModel : ViewModelBase
{
// ...
private string header;
public string Header
{
get
{
return header;
}
set
{
header = value;
OnPropertyChanged();
}
}
// ...
}
I have been using with great success with Askaiser.Mobile.Pillar, and I do not see anything wrong, I am still investigating, but this has become a great candidate for my projects.
Doc
I hope I have helped.
A greeting
The plain truth is that MVVM Frameworks (and their IOC Containers) are short-cuts to save you time. They come at an extraordinary expense:
They cause a simplistic alignment between views, view models and models. Only one can really belong to another. This is not "IOC" -- it's a hard-coded assignment based on a file naming convention such as this:
MainPage
MainViewModel
MainModel
In a real injection scenario, any number of models could serve any number of view models, provided they implement the proper interface. Also, any number of view models can serve any number of views as long as those view models support the views' interface(s).
MVVM Frameworks create classes through a reflection trick using a string prefix. In the example earlier, the string "Main" allows us to find the page, the view model and the model. But this is not view-model-to-view-model navigation. It is string to view model navigation.
The frameworks create classes using Activator.CreateInstance, which creates havoc on the compile-time linker.
The frameworks instantiate using hyper-simplistic constructor parameter logic. Modern programs use instantiation as a form of control. In these frameworks, there is no real control.
The complete code for these remarks is at https://github.com/marcusts/xamarin-forms-annoyances. See the solution called MvvmAntipattern.sln.
The GitHub site also provides links to a more detailed discussion on this topic.
here is my "problem" I want to resolve:
I have got many "View only" specific functionalities for example:
Change the ResourcesDictionary of a View at runtime (for changing skins from black to blue or whatever)
Save and restore View specific settings like the view size, or grid properties set by a user
...
All those functionalities have nothing to do with the ViewModel, since they are really view specific and might only fit to one client (View) of a ViewModel (in the case a ViewModel has got more than one client). The examples above are only two of a large amount of functionalities I want to implement, so I need a more generic solution instead of solutions that only fit those two examples.
When thinking of a solution I came two the following approaches
Create a ViewBase that inherits from DependancyObject. I dont like this solution because it somehow breaks the idea of the MVVM pattern where a View has no code behind. And to call this methods I somehow need to reference the View in my ViewModel which also negates the idea of seperation of concerns.
Create an IView interface. As dirty as the first approach. Each View needs to implement IView and therfor has code behind. Also the ViewModel needs to "somehow" know the IView implementation to call its methods
Bind Properties of the ViewModel to Triggers, Behaviours, Commands of the View. This approach seems to be the best, but I think I will run in a limitation of usage very fast because some functionalities might not work with this approach. For example just Binding a resourceDictionary to a View might not work because a merge is needed for correct display of new resources. Then again...I have view only specific functionalities / informations (like a resourcesdictionary) in the ViewModel, but only a specific client of the ViewModel uses this property.
If anyone of you already had the same problem and got a smart/smooth (and mostly generic ;) ) solution for my problem, this would be great.
Thank you
The easiest way to do that without introducing coupling between the View and ViewModel is to use a Messenger (also called Mediator in some frameworks). The ViewModel simply broadcasts a "change theme" message, and the View subscribes to that message. Using the Messenger class from MVVM Light, you could do something along those lines:
Message definition
public class ThemeChangeMessage
{
private readonly string _themeName;
public ThemeChangeMessage(string themeName)
{
_themeName = themeName;
}
public string ThemeName { get { return _themeName; } }
}
ViewModel
Messenger.Default.Send(new ThemeChangeMessage("TheNewTheme");
View code-behind
public MyView()
{
InitializeComponent();
Messenger.Defaut.Register<ThemeChangeMessage>(ChangeTheme);
}
private void ChangeTheme(ThemeChangeMessage msg)
{
ApplyNewTheme(msg.ThemeName);
}
I've long since adopted the way of thinking that Patterns were made for Man, not Man for patterns. Quite often you'll see a situation where MVVM doesn't fit and to resolve it, very smart people have come up with ways to get around it, while maintaining the pure MVVM look.
However, if you subscribe to my school of thought, or if you just like to keep it simple, another way is to allow the ViewModel to reference the view; via an interface of course, or that would just be terrible programming practice. Now the question becomes, how to get the view into the viewmodel?
the simplest way would be to do this in the view's dataContextChanged event. However if you want to try something different, how about using an attached property or dependency property to inject the view into the viewmodel?
I've successfully used this techniques on a number of WPF projects and don't feel dirty or somehow compromised. I call it MiVVM or Model Interface-to-View ViewModel.
The pattern is simple. Your Usercontrol should have an interface, call it IMyView. Then in the ViewModel you have a property with a setter of type IMyView, say
public IMyView InjectedView { set { _injectedView = value; } }
Then in the view you create a dependency property called This
public MyUserControl : IMyView
{
public static readonly DependencyProperty ThisProperty =
DependencyProperty.Register("This", typeof(IMyView), typeof(MyUserControl));
public MyUserControl()
{
SetValue(ThisProperty, this);
}
public IMyView This { get { return GetValue(ThisProperty); } set { /* do nothing */ } }
}
finally in Xaml you can inject the view directly into the ViewModel using binding
<MyUserControl This="{Binding InjectedView, Mode=OneWayToSource}"/>
Try it out! I've used this pattern many times and you get an interface to the view injected once on startup. This means you maintain separation (Viewmodel can be tested as IView can be mocked), yet you get around the lack of binding support in many third party controls. Plus, its fast. Did you know binding uses reflection?
There's a demo project showcasing this pattern on this blog link. I'd advocate trying out the Attached Property implementation of MiVVM if you are using a third party control that you cannot modify.
Finally may I suggest to find the best tool for the job is almost always the best programming approach. If you set out to right "clean" or "correct" code you are often going to hit a wall where you need to change your approach throughout.
When you said
I have got many "View only" specific functionalities for example:
that makes me think that you are mixing the "What" and the "How". I'll explain what I mean by this.
The what is your app requirements:
Change skin color of app
Save & Restore
Size
Grid properties
I argue that the above has everything to do with your ViewModel, your VM should contain simple or complex properties that can tell your View what it wants to do e.g.
public class SettingsViewModel
{
public Color Skin { get;set;}
public Size ViewSize {get;set;}
public GridProperties GridProperties {get;set;}
public void Save() {//TODO:Add code}
public void Restore() {//TODO:Add code}
}
your View would bind to that ViewModel and implement the "How".
If you're creating a web app then the how will take the ViewModel and create html. If you're using WPF you bind to those properties in XAML and create your UI(which might cause you to switch out ResourceDictionaries etc.)
Another thing that helped me out is to realize the asymmetrical relationship between the View and the ViewModel. In it's purest form the ViewModel should know nothing of the View, but the View should know everything it needs to know about the ViewModel.
That's the whole point behind separation of concerns.
Responses to your "solutions":
Your first option violates MVVM principles, have you read this article?
I believe this article will help you come to terms with view selection based on the ViewModel.
I don't know of what "limitations" you will come across, but WPF is quite robust and there will be solutions available.
I agree that View specific functionality should stay in the View (Save and Restore the window size, set focus to a specific control, etc.).
But I don’t agree that the introduction of an IView interface is ‘dirty’. That’s a common design pattern called Separated Interface which is described in Martin Fowler’s book Patterns of Enterprise Application Architecture. Furthermore, code-behind is not ‘evil’ as long the code relates to View specific functionalities. Unfortunately, that’s a common misunderstanding in the MVVM community.
If you give the introducing of an IView interface approach a change then you might find the WPF Application Framework (WAF) interesting. It solves our issues through this interface. You are going to see this in the sample applications.
I have a singleton Model and ViewModel objects and would like to programmatically create and attach WPF views to them, one at a time. Views can be created dynamically, say by selecting a menu item (somewhere). Newly created view would dispose of any old view looking at a ViewModel. Then it would make itself a current view of that ViewModel, displaying it in some WPF window serving as a container for view UserControl. I am using MEF for IoC. It is important that Model and ViewModel objects are created only once. What would be the way to accomplish this using MEF?
You might have a look at the ViewModel and Writer sample applications of the WPF Application Framework (WAF). They show how to switch a view using MVVM and MEF.
I use viewmodel first approach in my testapps. so i instantiate viewmodel via mef and then wpf + datatemplates do the rest. all i have to do is binding my actual viewmodel to the contentcontrol.content.
you say that its important that ViewModel objects just created once. you achieve this with mef and creationPolicy.Shared or Lazy<> import. with this in mind i think ViewModel-First is the way you should go. its straightforward and you need no extra locator or wathever :)
I'm using MVVM in a WPF app. I'm very new to both. Let me state that I am not a purist in the MVVM pattern, I am trying to use as many best practices as I can but am trying to make what I think are reasonable compromises to make it work in our environment. For example, I am not trying to achieve 0% code in my View code-behind.
I have a couple of questions about best practices.
1) I understand I don't want my VM to know about the attached View, but is it reasonable for the View to have a reference to its VM?
2) If a control in a View opens another View (such as a dialog) should I handle this in the View? It seems wrong to handle it in the VM since then the VM has some knowledge of a specific View.
1) The View has definitely a reference to the ViewModel through the DataContext. And you are allowed to cast the DataContext in your View:
public class ShellView : Window
{
…
public ShellViewModel { get { return DataContext as ShellViewModel; } }
This isn’t a violation with the Model-View-ViewModel pattern.
.
2) You are right. A ViewModel shouldn’t open another View. A better approach is to use Controllers. They are responsible for the Workflow of an application.
If you are interested in more detailed information then you might have a look at the WPF Application Framework (WAF).
1) Here are two simple practices for View's "knowing about" a ViewModel. It's reasonable for a View to know about a ViewModel (for Data Binding) -- but you may not need it in your case. See if either of these approaches help solve your problem. There are other ways, but these should be simple enough:
public View(ViewModel vm)
{
View.DataContext = vm;
}
public Bootstrapper(View v, ViewModel vm)
{
v.DataContext = vm;
//or, if you want it to have no parameters
View v = new View();
ViewModel vm = new ViewModel();
v.DataContext = vm;
}
The first option isn't bad if you have a service location tool, but there is a flavor of MVVM that doesn't like any code in the View's Code-Behind. The second option isn't bad either, should be simple enough for your task.
2.) This question can be a bit of a sticky point in MVVM design. If we are talking about a general Win32 MessageBox, I will often separate that logic into an additional object and put it in the VM. This way tends to a little more clear. (For example, I have selected an item in a ListBox, I have attached a Delete ICommand to that action, and in my ViewModel when this ICommand is Executed, I will poke my MessageBoxObject to ask if the user "wants to really delete" this item). More advanced "Dialogs" would use additional ViewModels and DataTemplates for those ViewModels. I prefer the Mediator approach.
1). The view will need a reference to the view model at some level, since the viewmodel will act as the view's datacontext.
2) One way to handle this is to have a generalized viewmodel representing a dialog, that is owned by the main viewmodel (the one being used as the views datacontext.)
You can use a command to crate a new instance of a dialog viewmodel, which will have a corresponding datatemplate defined in your resources. This template will be set to bind to the dialogviewmodel type.
Quite late, but I think this is tricky enough to deserve lots of different perspectives.
I understand I don't want my VM to know about the attached View, but
is it reasonable for the View to have a reference to its VM?
As already answered, a proper View-ViewModel arrangement involves the ViewModel being assigned as the View's DataContext property. That allows DataBindings to be "automagically" established from declarative XAML, or fine-tuned via code behind.
Sometimes, you'll be tempted to write, in your code behind, something like this:
var dc = DataContext as CleverViewModel;
CleverViewModel.CleverProperty.Add(someValue); // just a simple example
I believe the proper way to achieve this sort of things is NOT to cast DataContext, but instead:
Have some dedicated control in View, for example an ItemsControl with its ItemsSource two-way databound to some property in viewmodel:
<ItemsSource x:Name="cleverControl" Visibility="Collapsed" ItemsSource="{Binding CleverProperty, Mode=TwoWay}"/>
Cast the bound property instead of the whole ViewModel, in code behind:
var collection = (ObservableCollection<double>)cleverControl.ItemsSource;
collection.Add(someValue);
Note the important difference: the second approach in this example doesn't require the View to know the ViewModel type, it only needs a property named CleverProperty of type ObservableCollection<double>. This allows me to have polymorphic or even duck-typed ViewModels.
If a control in a View opens another View (such as a dialog) should I
handle this in the View? It seems wrong to handle it in the VM since
then the VM has some knowledge of a specific View.
This shouldn't happen in strict MVVM, and its not difficult to avoid using DataTemplates. DataTemplates map a given type of DataContext to a given type of view, so anytime the datacontext of a ContentControl changes, its display also changes, provided that you have a DataTemplate for that type:
A control in the view could send a command to the ViewModel, which in turn would update some of its own properties, that would be reflected by the view.
A View could contain another View, outside the knowledge of the ViewModel. In this case, the code behind can manipulate the datacontext of the contained view.
There are more subtleties, but I have been using this approach with good results. Hope this helps someone.
Build Your Own MVVM Framework
I found the approach suggested by Rob Eisenberg very interesting.
Key points:
Convention over configuration
ViewModel first
Which is very similar to ASP.NET MVC philosophy.
I highly recommend watching the video.