ASP.NET MVP Pattern - c#

I'm trying to implement the Model-View-Presenter design pattern in my application.
The general concept of the MVP pattern is known for me, but I'm more struggling with getting it done using nested usercontrols.
I've got a few possible scenarios I might be able to implement, but before doing so I'd like to hear your opinion.
I think it does not matter to post any of my code, since its more a "concept" I'm trying to understand.
So the scenario is:
1 page used to connect 2 user controls. One of these usercontrols contains a child usercontrol. How do I work around with MVP pattern in this case?
1 Page
1 UC
1 UC
1 SubUC
Edit:
So basicly what I want to know is how we can interact between two views (parent and child) using MVP in both usercontrols.
I'll show you an example in ASP.net WITHOUT MVP:
http://pastie.org/5452134
Now with MVP, do we still register to this kind of event using the CodeBehind? Knowing that this parent and child usercontrol would both be using the MVP pattern. Or does the presenter get's included in this interaction?
Eventually I can change the code to:
http://pastie.org/5452180
But I'm wondering whether this is OK, considering the MVP pattern...
Or do we more need an approach like this:
http://pastie.org/5452174
All the above examples are written in the CodeBehind of the parent view. Is one of this correct? If not, how can we achieve this using a better approach
Edit 2: I've added a solution with my example approach at: https://github.com/frederikprijck/ASP.NET-MVP
I think this should be pretty much what I wanted...

I don't see a problem - user control is nothing but a view. And a presenter can interact with multiple views at a time. So in this case, your presenter can have reference of say 4 views (one for page, two for user controls and last one for sub-user control).
Alternatively, you want to have single view per presenter and in such case, you can see user control as child view of the parent view(page) and so parent view need to bubble up and down view interactions meant for presenter. However, I would prefer the earlier approach where presenter handling interaction multiple views.
See this related question on SO on how wiring is done: https://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts
Finally, you may want to look at MVVM pattern which I believe works great for compositional UI. Instead of presenter, you will have view model that will control the interaction between view and model - however, unlike presenter, view model does not know about view - rather view observes (and updates) view model to render itself. See this article here (View Model is referred as Presentation Model): http://www.codeproject.com/Articles/23340/Presentation-Model-in-Action
EDIT:
To be honest, I don't prefer any of your approaches. I like MVP implementation where presenter holds reference to view via interface (no tight coupling) and view does the wiring i.e. creates presenter instance and inject the view references. The presenter listens to view events and call methods on view. View never calls directly on presenter's methods. (Other variations of MVP are possible - see the SO answer that I had sought). With this, I will explain two approaches that I had explained earlier.
Approach 1:
Each user control is an independent view. There will be common presenter that will handle multiple views. For example,
public class Presenter1
{
IView1 _view1;
IView2 _view2;
public Presenter1(IView1 view1, IView2 view2)
{
_view1 = view1;
_view2 = view2;
_view1.OnSave += OnSave;
_view1.OnSomeEvent += OnSomeEvent;
_view2.OnFoo += OnFoo;
}
public void OnSave()
{
var data1 = _view1.GetData();
var data2 = _view2.GetData();
// update model
...
}
public void OnSomeEvent()
{
// inform view2 about it
_view2.DoOnSomeEvent();
}
...
}
public partial class MyPage : Page, IView1
{
public void Page_Load(...)
{
//do wire up
_presenter = new Presenter(this, usercontrol1);
}
...
}
Basic idea is that view does not do cross talk. If user control needs to inform page some thing, it would raise an event that is caught by presenter and it informs page about it. Views are passive and handles UI.
Approach 2:
Usercontrol and Page interacts. In such case, Page will act as a ultimate view and Presenter will hold reference to it. Control's events will be handled by page and page will bubble up the event if necessary. For example,
IView1 : IView2 { }
public class Presenter1
{
IView1 _view1;
public Presenter1(IView1 view1)
{
_view1 = view1;
_view1.OnSave += OnSave;
_view1.OnSomeEvent += OnSomeEvent;
_view1.OnFoo += OnFoo;
}
...
}
public partial class MyPage : Page, IView1
{
public void Page_Load(...)
{
//do wire up
_presenter = new Presenter(this);
// handle user control events
UserControl1.Foo += UserControl1_OnFoo();
UserControl1.XyzEvent += UserControl1_XyzEvent();
}
...
private void UserControl1_OnFoo(...)
{
// bubble up to presenter
OnFoo(..)
}
private void UserControl1_XyzEvent(...)
{
// private interaction (purely about some UI manipulation),
// will not be bubble up to presenter
...
}
}

Related

WPF - MVVM view model first

I am building a large scale WPF app - kind of a desktop that hosts multiple modules such as multiple Terminal windows over RS232/Ethernet, Register analyzer, automation tools, etc.
I am working with MVVM architecture where my view (XAML) instantiate the corespondent viewmodel in its resource section. and the view model is set in the data-context of the view.
in this method the view created first.
however, I red about another method called VM first, meaning view model is instantiated before the view, and I understood the theory that stands behind it. What I didn't understand is when and who instantiate the view and how it happens without coupling to the view.
I'll be more than happy to hear your thoughts, and please if someone can supply code samples it would be great..
Thanks in advance.
I'm using MVVM heavily in my projects and can share my view on this.
In my projects the view never instantiates any VM. Usually I have some kind of manager which takes care that the corresponding VM is created.
This I'm assign to the datacontext of some top-level UI control (Window for instance). The view is always defined by a style where the target type is set to the type of the view model.
The startup code just creates a Window and the main viewmodel. The VM is assigned and the rest is done by the WPF (.net) runtime so to say.
So I have a large style file, where all the styles for each viewmodel defines the corresponding view (usually a usercontrol).
This is the way I'm doing things, there are for sure others too.
hth
In my WPF / MVVM applications I use ViewModels with two constructors - one for design time (no paramaters - mock version of required components are set directly) and another for runtime (required components are injected as parameters via IoC). This allows for (mock) data to be displayed inside the Visual Studio designer for UI testing purposes.
So the simple case looks like ...
public class MainViewModel : ViewModelBase
{
private IDataFactory _DataFactory;
public MainViewModel()
{
_DataFactory = new DesignTimeMockDataFactory();
LoadData();
}
[PreferredConstructor]
public MainViewModel(IDataFactory dataFactory)
{ _DataFactory = dataFactory; }
public void LoadData()
{ DataItems.AddRange(_DataFactory.GetDataItems()); }
public ExtendedObservableCollection<DataItem> DataItems { get; private set; }
}
The design time usage can be set directly in the XAML ...
<Window x:Class="MainView"
d:DataContext="{d:DesignInstance Type=MainViewModel, IsDesignTimeCreatable=True}"
...
The run-time ViewModel is set in the code behind of the View ...
public MainView()
{
InitializeComponent();
var viewModel = SimpleIoc.Default.GetInstance<MainViewModel>();
DataContext = viewModel;
Loaded += (s, e) => viewModel.LoadData();
}
The View's Loaded event is set to call the LoadData() method of the ViewModel to trigger data loading, once the View is displayed. If LoadData() is slow, it can be changed into an async method to prevent the UI from blocking.
For those of you complaining that this is a too tightly coupled construct, my view is that is exactly how they are supposed to be. Although the View and ViewModel are separate entities, each View knows exactly what type of ViewModel it requires, and that's unlikely to change over the project development life-cycle. Using a Locator type class to hide the ViewModel constructor calls is an unnecessary level of abstraction in my opinion.
To decouple the view from the view-model, something else needs to instantiate the view model and manage its lifetime and sharing. That job might fall to an IoC container, or simple, manual dependency injection. It's entirely up to you.
E.g. from Paul Stovell's article:
public CalculatorView(CalculatorViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
It all depends on you're trying to achieve by decoupling. One reason might be so that you can have multiple views over the same view-model - in that case, whatever creates the views needs to also create the view-model.
Another may be to swap the view-model of an existing view out with another view-model without destroying the view. In that case, maybe you already have two existing view-models and you assign them to the view's DataContext as required.
view.DataContext = viewModels[0];
view.DataContext = viewModels[1];
when your application grows you usually face these decisions. Usually you have "always" both elements together the View and the ViewModel it's not about what comes first it's more like what will you use to instantiate the two elements (view and viewmodel).
For larger projects, when I had the need, I used a class called ViewModelResolver. It obviously has an interface IViewModelResolverso it can be injected nicely.
It can either return a ViewModel based on convention based on type or a string representation and uses reflection to instantiated it.
You can also pass in a ViewModel (or type) and get the matching view with the passed in view model as DataContext (view ViewModel marriage) or you can define other custom scenarios that you need for instantiating either view or ViewModel.
hope that helps
So the main point is to have an intermediate class that acts like some sort of factory service that takes car of bringing views and view models together and instantiate them.
This gives you more freedom and a good place to separate out those decisions from the ViewModel directly.

MVVM when to create a viewmodel for a control?

Or should I only create viewmodels for the domain data being represented? While reading on MVVM, I came across this:
"The ViewModel is responsible for these tasks. The term means "Model of a View", and can be thought of as abstraction of the view, but it also provides a specialization of the Model that the View can use for data-binding. In this latter role the ViewModel contains data-transformers that convert Model types into View types, and it contains Commands the View can use to interact with the Model. "
http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx
If the viewmodel is a model of the view, then doesn't it make sense to put properties of the view in the viewmodel rather than on the code behind of the view itself?
I guess in making a custom control I just have a hard time deciding when I should just add a property to the control's code behind and when it is worthwhile to make a viewmodel for the control to represent it. Honestly I kind of feel that moving all of the control's view related properties to the viewmodel would clean up the code behind of the control leaving only the control logic.
However, if I were to change things like this, then at times when an item needs properties from the control itself I can no longer use {Binding ElementName = control, Path=property} and have to instead get the data context of the parent (because the current datacontext would be on the individual subitem of the observable collection.
Basically I was considering whether I should move properties from Class GraphViewer into a GraphViewerViewModel and then just bind to it.
Code is worth a million words so:
public class GraphViewerViewModel :DependencyObject
{
private const int DEFAULT_PEN_WIDTH = 2;
private const int DEFAULT_GRAPH_HEIGHT = 25;
public SignalDataViewModel _SignalDataViewModel
{
get;
set;
}
public PreferencesViewModel _PreferencesViewModel
{
get;
set;
}
}
Meanwhile
public class SignalDataViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
ObservableCollection<SignalViewModel> _signals;
public ObservableCollection<SignalViewModel> Signals
{
get
{
return _signals;
}
private set
{
_signals = value;
}
}
ObservableCollection<SignalViewModel> _AddedSignals;
public ObservableCollection<SignalViewModel> AddedSignals
{
get
{
return _AddedSignals;
}
private set
{
_AddedSignals = value;
}
}
it is a pain to type:
PenWidth="{Binding RelativeSource = {RelativeSource AncestorType={x:Type DaedalusGraphViewer:GraphViewer}},
Path = _GraphViewerViewModel._SignalDataViewModel._AxisDivisionUnit.GraphPenWidth, Mode=OneWay}"
and I'm wondering if it is worthwhile to make the change or whether I'm misunderstanding what a view model should be used for in mvvm.
I guess in making a custom control I just have a hard time deciding when I should just add a property to the control's code behind and when it is worthwhile to make a viewmodel for the control to represent it. Honestly I kind of feel that moving all of the control's view related properties to the viewmodel would clean up the code behind of the control leaving only the control logic.
In general, a custom control is 100% View layer code. As such, it really falls outside of MVVM entirely.
The main goal when making a custom control to be used within an application being designed with MVVM is to make sure that you design and build the custom control in a way that it is fully compatible with data binding. This will allow it to be used within your View layer of your application exactly like other controls.
As such, this pretty much guarantees that you'll have code behind, since implementing Dependency Properties really requires code behind. You also don't want to set the DataContext of a custom control within the control (since you want to inherit the data context of the user control or window using the control).
Basically I was considering whether I should move properties from Class GraphViewer into a GraphViewerViewModel and then just bind to it.
If the types are specific to your domain, then this is really typically more of a UserControl being used by your application. In that case, creating a ViewModel and just binding is likely good.
If this is, on the other hand, a true custom control that's made to be completely general purpose (ie: usable by anybody in any application), then keeping it as a "pure view" custom control typically means that you 1) won't take a dependency on any ViewModels or domain specific objects, and 2) not set the data context (which means no view model).

Conditionally auto-click button in MVVM using xaml

I am writing an application based on MVVM architecture. The application has a Wizard like workflow. In couple of pages (views) in my application, I need a button to be auto-clicked when a certain condition is satisfied. The views are tied together using the root Wizard view model which has a ClickNextBtn command that is tied to the Next button in the root Wizard view. So, I need something like in the root Wizard view:
<DataTrigger Binding="{Binding Path=CanAutoClickNext}" Value="True">
<Setter Property="ClickBtn" Value="true" />
</DataTrigger>
The property in the above sample is meaningless, but hopefully it helps convey what I am trying to do.
The CanAutoClickNext bool property is available off of the Wizard view model.
On one of the views where I need the Next button auto-clicked, I tried passing the WizardViewModel as an argument to its corresponding view model's constructor when it is first instantiated in the root wizard view model, and then calling the ClickNextBtn off of it in a method therein later when the view is actually loaded. But that did not work, not surprisingly.
I know how to programmatically click a wpf button, but getting it all tied together in the framework I have is proving to a big challenge. Any feedback is appreciated.
UPDATE:
I ended up rewriting the UI design pattern (still MVVM) so that now instead of having to having to move to a next page automatically, the state within a page changes and a different set of controls become active. Users are then prompted to click next.
Like the comment's on your question stated, this should be a concern of the ViewModel to invoke the Click Handler.
How you could go about implementing this is very similar to something like this Question's answer
Now in MVVM, you should have your Button's connected to an ICommand in the ViewModel(If your using MVVM Light toolkit, it will be RelayCommand/RelayCommand<T>).
Now assuming this ICommand variable in your VM is called NextButtonCommand,
what you can do is
public bool CanAutoClickNext {
get {
return _canAutoClickNext;
}
private set {
if (value == _canAutoClickNext)
return;
_canAutoClickNext = value;
RaisePropertyChanged(() => CanAutoClickNext);
if (_canAutoClickNext)
NextButtonCommand.Execute(null);
}
}
with this, when your property in the VM CanAutoClickNext gets set to "True", the Execute function of the ICommand is automatically invoked by the VM. This seperates all the logic handling to the VM and keeps the View dumb as what is recommended by MVVM when it comes to application / business logic.
Side Note
The property CanAutoClickNext seems a waste if it's not being bound to anything from the View. If this is the case, I'd recommend just getting rid of that property and invoke the ICommand.Execute(null) from the place where the logic holds fit than use a property with INPC just for this case.
I'll follow up from a different angle. Let's say you have any message bus ready (IEventAggregator, IMessenger, doesn't matter). I'll use the Caliburn.Micro's IEventAggregator along with the nomenclature 'cause that's what I'm most familiar with. Now you might have a very simple event:
public class MoveNext
{
}
Then your 'host' viewmodel of the wizard:
public class WizardHost : IHandle<MoveNext>
{
private readonly IEventAggregator messageBus
public WizardHost(IEventAggregator messageBus)
{
this.messageBus = messageBus;
this.messageBus.Subscribe(this);
}
/here you might have the 'real' command method, e.g:
public void GoToNextQuestion()
{
// do stuff
}
public void Handle(MoveNext message)
{
GoToNextQuestion();
}
}
public class WizardPage
{
private readonly IEventAggregator messageBus;
private bool shouldMoveToNext;
public WizardPage(IEventAggregator messageBus)
{
this.messageBus = messageBus;
}
public void DoStuff()
{
//at some point, you might want to switch the flag or do whatever you need/want to do and:
if(shouldMoveToNext)
messageBus.Publish(new MoveNext());
}
}
Now when you DoStuff() in your wizard page, you can publish the event and the 'host' page will react and flip the page.
That's of course all nice if you're using any MVVM framework that's out there. MVVM Light has the Messenger, Caliburn.Micro has - as you might have noticed - IEventAggregator.

Winforms and the MVP Design Pattern? [duplicate]

I am trying to implement the MVP method for the first time, using WinForms.
I am trying to understand the function of each layer.
In my program I have a GUI button that when clicked upon opens a openfiledialog window.
So using MVP, the GUI handles the button click event and then calls presenter.openfile();
Within presenter.openfile(), should that then delegate the opening of that file to the model layer, or as there is no data or logic to process, should it simply act on the request and open the openfiledialog window?
Update: I have decided to offer a bounty as I feel I need further assistance on this, and preferably tailored to my specific points below, so that I have context.
Okay, after reading up on MVP, I have decided to implement the Passive View. Effectively I will have a bunch of controls on a Winform that will be handled by a Presenter and then the tasks delegated to the Model(s). My specific points are below:
When the winform loads, it has to obtain a treeview. Am I correct in thinking that the view should therefore call a method such as: presenter.gettree(), this in turn will delegate to the model, which will obtain the data for the treeview, create it and configure it, return it to the presenter, which in turn will pass to the view which will then simply assign it to, say, a panel?
Would this be the same for any data control on the Winform, as I also have a datagridview?
My App, has a number of model classes with the same assembly. It also supports a plugin architecture with plugins that need to be loaded at startup. Would the view simply call a presenter method, which in turn would call a method that loads the plugins and display the information in the view? Which tier would then control the plugin references. Would the view hold references to them or the presenter?
Am I correct in thinking that the view should handle every single thing about presentation, from treeview node colour, to datagrid size, etc?
I think that they are my main concerns and if I understand how the flow should be for these I think I will be okay.
This is my humble take on MVP and your specific issues.
First, anything that a user can interact with, or just be shown, is a view. The laws, behavior and characteristics of such a view is described by an interface. That interface can be implemented using a WinForms UI, a console UI, a web UI or even no UI at all (usually when testing a presenter) - the concrete implementation just doesn't matter as long as it obeys the laws of its view interface.
Second, a view is always controlled by a presenter. The laws, behavior and characteristics of such a presenter is also described by an interface. That interface has no interest in the concrete view implementation as long as it obeys the laws of its view interface.
Third, since a presenter controls its view, to minimize dependencies there's really no gain in having the view knowing anything at all about its presenter. There's an agreed contract between the presenter and the view and that's stated by the view interface.
The implications of Third are:
The presenter doesn't have any methods that the view can call, but the view has events that the presenter can subscribe to.
The presenter knows its view. I prefer to accomplish this with constructor injection on the concrete presenter.
The view has no idea what presenter is controlling it; it'll just never be provided any presenter.
For your issue, the above could look like this in somewhat simplified code:
interface IConfigurationView
{
event EventHandler SelectConfigurationFile;
void SetConfigurationFile(string fullPath);
void Show();
}
class ConfigurationView : IConfigurationView
{
Form form;
Button selectConfigurationFileButton;
Label fullPathLabel;
public event EventHandler SelectConfigurationFile;
public ConfigurationView()
{
// UI initialization.
this.selectConfigurationFileButton.Click += delegate
{
var Handler = this.SelectConfigurationFile;
if (Handler != null)
{
Handler(this, EventArgs.Empty);
}
};
}
public void SetConfigurationFile(string fullPath)
{
this.fullPathLabel.Text = fullPath;
}
public void Show()
{
this.form.ShowDialog();
}
}
interface IConfigurationPresenter
{
void ShowView();
}
class ConfigurationPresenter : IConfigurationPresenter
{
Configuration configuration = new Configuration();
IConfigurationView view;
public ConfigurationPresenter(IConfigurationView view)
{
this.view = view;
this.view.SelectConfigurationFile += delegate
{
// The ISelectFilePresenter and ISelectFileView behaviors
// are implicit here, but in a WinForms case, a call to
// OpenFileDialog wouldn't be too far fetched...
var selectFilePresenter = Gimme.The<ISelectFilePresenter>();
selectFilePresenter.ShowView();
this.configuration.FullPath = selectFilePresenter.FullPath;
this.view.SetConfigurationFile(this.configuration.FullPath);
};
}
public void ShowView()
{
this.view.SetConfigurationFile(this.configuration.FullPath);
this.view.Show();
}
}
In addition to the above, I usually have a base IView interface where I stash the Show() and any owner view or view title that my views usually benefit from.
To your questions:
1. When the winform loads, it has to obtain a treeview. Am I correct in thinking that the view should therefore call a method such as: presenter.gettree(), this in turn will delegate to the model, which will obtain the data for the treeview, create it and configure it, return it to the presenter, which in turn will pass to the view which will then simply assign it to, say, a panel?
I would call IConfigurationView.SetTreeData(...) from IConfigurationPresenter.ShowView(), right before the call to IConfigurationView.Show()
2. Would this be the same for any data control on the Winform, as I also have a datagridview?
Yes, I would call IConfigurationView.SetTableData(...) for that. It's up to the view to format the data given to it. The presenter simply obeys the view's contract that it wants tabular data.
3. My App, has a number of model classes with the same assembly. It also supports a plugin architecture with plugins that need to be loaded at startup. Would the view simply call a presenter method, which in turn would call a method that loads the plugins and display the information in the view? Which tier would then control the plugin references. Would the view hold references to them or the presenter?
If the plugins are view-related, then the views should know about them, but not the presenter. If they are all about data and model, then the view shouldn't have anything to do with them.
4. Am I correct in thinking that the view should handle every single thing about presentation, from treeview node colour, to datagrid size, etc?
Yes. Think about it as the presenter providing XML that describes data and the view that takes the data and applies a CSS stylesheet to it. In concrete terms, the presenter might call IRoadMapView.SetRoadCondition(RoadCondition.Slippery) and the view then renders the road in red color.
What about data for clicked nodes?
5. If when I click on the treenodes, should I pass through the specific node to the presenter and then from that the presenter would work out what data it needs and then asks the model for that data, before presenting it back to the view?
If possible, I would pass all data needed to present the tree in a view in one shot. But if some data is too large to be passed from the beginning or if it's dynamic in its nature and needs the "latest snapshot" from the model (via the presenter), then I would add something like event LoadNodeDetailsEventHandler LoadNodeDetails to the view interface, so that the presenter can subscribe to it, fetch the details of the node in LoadNodeDetailsEventArgs.Node (possibly via its ID of some kind) from the model, so that the view can update its shown node details when the event handler delegate returns. Note that async patterns of this might be needed if fetching the data might be too slow for a good user experience.
The presenter, which contains all logic in the view, should respond to the button being clicked as #JochemKempe says. In practical terms, the button click event handler calls presenter.OpenFile(). The presenter is then able to determine what should be done.
If it decides that the user must select a file, it calls back into the view (via a view interface) and let the view, which contains all UI technicalities, display the OpenFileDialog. This is a very important distinction in that the presenter should not be allowed to perform operations tied to the UI technology in use.
The selected file will then be returned to the presenter which continues its logic. This may involve whatever model or service should handle processing the file.
The primary reason for using an MVP pattern, imo is to separate the UI technology from the view logic. Thus the presenter orchestrates all logic while the view keeps it separated from UI logic. This has the very nice side effect of making the presenter fully unit testable.
Update: since the presenter is the embodiment of the logic found in one specific view, the view-presenter relationship is IMO a one-to-one relationship. And for all practical purposes, one view instance (say a Form) interacts with one presenter instance, and one presenter instance interacts with only one view instance.
That said, in my implementation of MVP with WinForms the presenter always interacts with the view through an interface representing the UI abilities of the view. There is no limitation on what view implements this interface, thus different "widgets" may implement the same view interface and reuse the presenter class.
The presenter should act on the request end show the openfiledialog window as you suggested. Since no data is required from the model the presenter can, and should, handle the request.
Let's assume you need the data to create some entities in your model. You can either pass the stream trough to the access layer where you have a method to create entities from the stream, but I suggest you handle the parsing of the file in your presenter and use a constructor or Create method per entity in your model.

Updating a viewmodel from another viewmodel

I have two ViewModels one is attached to a main window and the other is attached to child window that is opened by clicking on a button on the main window. The child window contains a list of items and I want to select an item and display it in the main window by updating the main window viewmodel. What is the best way to accomplish this. Thanks!
There are any number of ways to do this.
Pass a reference to the main/parent view model into the child and have the child call the main view model.
Have the child view model fire an event that the parent subscribes to.
Use a messenger/mediator to communicate between the two. The parent subscribes, the child posts the message. This provides loose coupling.
Set the main view model up as a global service. Register it somehow. Have the child look up the service (requiring global services is a pretty common problem) and then call something on the global/common interface.
From my experience, the simplest method would be #2. Define an event on the child view model. The parent will have to look up the child (I don't know if it contains it or how your view models are constructed) and subscribe to the event.
The standard way to communicate between ViewModels is to use Messaging of some sort. One good implementation of this is the MVVM Light Toolkit
Here's some (random) code using the default messenger therefrom:
//Registering:
Messenger.Default.Register<IEnumerable<BookViewModel>>(this, true, fillSourceWith);
Messenger.Default.Register<DisplayModeEnum>(this, ChangeMainTemplates);
//with a specific "token"
Messenger.Default.Register<object>(this, MessageTokens.ClearList, o => BookSource.Clear());
//Sending
Messenger.Default.Send<List<BookViewModel>>(newBooks);
Messenger.Default.Send<DisplayModeEnum>(DisplayModeEnum.MediumLayout);
Messenger.Default.Send<object>(null, MessageTokens.ClearList);
Best way to do it is to have some kind of reference from child to parent and to update this parent when closing the child.
Or you can have some kind of event on child and let parent listen on this event. You then raise this event when child closes.
Messaging is used when both ViewModels are logicaly unrelated.
[rant] Dont people even know basic principles of OOP or what?? [/rant]
I had the same problem a few days before ;-)
Finally I used a mediator to communicate both view-models. On fact I used the Messenger from MVVM Light.
public void Search(object parameter)
{
ChildWindow window = new ChildWindow();
SearchWindow pageSearch = new SearchWindow();
window.Content = pageSearch;
window.Show();
Messenger.Default.Register<Messages.CloseWindowMessage>(this, action => this.closeWindow(action));
}
After that I defined the Message with everything I needed to know from main window:
public class CloseWindowMessage : MessageBase
{
public bool Result { get; set; }
public Model.Selected Selected { get; set; }
}
Finally the message back from the childwindow you only have to register the message with result and the object you want to get back.
You should register from the code-behind of your view to close the window.
I think best way to pass the message between two view models is event programming.

Categories

Resources