I'm dealing with a big problem for developing my app. It's a Winforms base application on C# implementing the Model-View-Presenter pattern, but I am new to this method. I've searched everywhere and haven't found an answer to my issue.
I need to know how I can use this pattern to allow communication between winforms, and how the presenter must show them without coupling the presenter to the form. I've seen a way using Factory pattern, but don't understand how to implement it.
Any help or point in the right direction would be appreciated.
Assertion
The Presenter is responsible for coordination between the View and Model (if following the Passive View implementation).
This could look like:
A View instantiating the Presenter and injecting itself into the Presenter:
IPresenter presenter;
public View() { presenter = new Presenter(this) }
A Presenter instantiating one or more views and injecting itself into the view(s):
IView1 view1;
public Presenter() { view1 = new View1(this) }
IView1 view1;
IView2 view2;
public Presenter() { view1 = new View1(this); view2 = new View2(this); }
Example
In your case, a Presenter coordinating multiple views might look something like this (pseudo):
public class Presenter : IPresenter
{
IView1 view1;
IView2 view2;
public Presenter()
{
view1 = new View1(this);
view2 = new View2(this);
}
private WireViewEvents()
{
view1.OnButtonClick += HandleButtonClickFromView1;
}
public void HandleButtonClickFromView1()
{
view2.SetSomeData();
view2.Show();
}
In this example, an event raised by View1 is handled by the Presenter, data is set in View2, and View2 is shown.
Keep in mind that no matter what your implementation is, the goals of MVP are:
Separation of concerns (UI seperate from domain logic).
Increasing testability.
Keep that this is just a basic example of how a Presenter might coordinate multiple views. If you want to abstract your View creation from the presenter you might move the creation into another container that the Presenter calls in to to create Views and subscribe to their events.
In MVP ,winforms should not communicate with each other.
Form A knows its Presenter A,
Form B knows its presenter B
Usually , you will modify model with form A through Prensenter A. Presenter B will listen to model changes,and will refresh Form B accordingly
If you need more coordination, you may consider using an Application Controller
See http://dotnetslackers.com/articles/designpatterns/The-Presenter-in-MVP-Implementations.aspx
I am just showing a dummy code in which 2 views are trying to communicate to each other through Presenter using interfaces. It is a simple example and let mw know if something is breaking. I have not tested this code to be honest.
namespace WindowsFormsApplication1
{
internal class View1 : IView1
{
public View1()
{
new Presenter(this);
}
public string Username { get; set; }
public event EventHandler ShowDetails;
}
}
namespace WindowsFormsApplication1
{
internal class View2 : IView2
{
public View2()
{
new Presenter(this);
}
public string Position { get; set; }
}
}
namespace WindowsFormsApplication1
{
public class Presenter
{
private readonly IView1 _view1;
private readonly IView2 _view2;
public Presenter(IView1 view1)
{
_view1 = view1;
_view1.ShowDetails += ShowDetails;
}
private void ShowDetails(object sender, EventArgs e)
{
_view2.Position = _view1.Username == "My Name" ? "Arhchitect" : "Project Manager";
}
public Presenter(IView2 view2)
{
_view2 = view2;
}
}
}
public interface IView1
{
string Username { get; set; }
event EventHandler ShowDetails;
}
public interface IView2
{
string Position { get; set; }
}
But after this example some notes. To start with your application try to decide first weather you want to go with 1 View interface or 2. There may be chances and even ease if you can use a single interface.
I think the points made earlier about the model raising events to make a presenter aware of changes is correct. I do have a couple comments I hope will be useful.
First, the View implementation might not be a single form. Sometimes, it makes sense for part of the model to be maintained by a separate (probably modal) form that really acts like a complex control in the View. In that case, the interaction between the forms would be direct. The Presenter should not care how the View implementation is done.
Second, when it looks like forms need to interact that are not clearly part of the same view (a lookup form, for example) I would recommand using the Application Controller pattern. In this case, when Form A needs to perform a function (like, "Find Product" or "Edit Details") it will call a method on it's own Presenter to do that. The Presenter then calls a separate method on the Application Controller (which all Presenters reference, it's a singleton) and the Application Controller opens the requried form which has its own Presenter. In WinForms, this could all be done with a modal form, in which case the results are sent back through the call chain. Alternatively, some event raising between the Application Controller and Presenters would be needed - i.e. the Presenter raises events on the Application Controller about what it has done and other Presenters substribing to that event are thus notified.
More on the Application Controller pattern in MVP can be found on my blog post Using the MVP Pattern
Related
I'm using the MVVM pattern in our WPF application to allow for comprehensive unit testing. The MVVM pattern itself is working great, however I'm struggling to adapt the pattern in a way that means I can use the design-time data support of WPF.
As I'm using Prism the ViewModel instances are generally injected into the constructor of the view, like so
public MyView(MyViewModel viewModel)
{
DataContext = viewModel;
}
Dependencies for the ViewModel are then injected into the constructor, like so
public class MyViewModel
{
public MyViewModel(IFoo foo, IBar bar)
{
// ...
}
// Gets and sets the model represented in the view
public MyModel { get; set; }
// Read-only properties that the view data binds to
public ICollectionView Rows { get; }
public string Title { get; }
// Read-write properties are databound to the UI and are used to control logic
public string Filter { get; set; }
}
This is generally working really well except when it comes to design data - I wanted to avoid compiling design-data specific classes into my released assembly and so I opted to use the {d:DesignData} approach instead of the {d:DesignInstance} approach, however in order for this to work correctly my ViewModel now needs to have a parameterless constructor. In addition, I also often need to change additional properties either to have setters or to be modifiable collections in order to be able to set these properties in XAML.
public class MyViewModel
{
public MyViewModel()
{
}
public MyViewModel(IFoo foo, IBar bar)
{
// ...
}
// Gets and sets the model represented in the view
public MyModel { get; set; }
// My read-only properties are no longer read-only
public ObservableCollection<Something> Rows { get; }
public string Title { get; set; }
public string Filter { get; set; }
}
This is worrying me:
I have a parameterless constructor that is never intended to be called and isn't unit tested
There are setters for properties that only the ViewModel itself should be calling
My ViewModel is now a jumbled mixture of properties that should be modified by the view, and those that shouldn't - this makes it tricky to tell at a glance which piece of code is responsible for maintaining any given property
Setting certain properties at design time (e.g. to see styling on the Filter text) can actually end up invoking ViewModel logic! (so my ViewModel also needs to be tollerant of otherwise mandatory dependencies being missing at design time)
Is there a better way to get design-time data in a WPF MVVM application in a way that doesn't compromise my ViewModel in this way?
Alternatively should I be building my ViewModel differently so that it has more simple properties with the logic separated out somewhere else.
First, I would recommend you to have a look at this video where Brian Lagunas provides several best practices about MVVM. Brian is - at least - involved in the development of Prism, as his name appears in the nuget packages information. Didn't check further.
On my side I only use bits of Prism, and my Model and ViewModel always offer blank constructors (like what Brian shows), the data context is assigned in the view's XAML, and I set the properties values like :
<MyView.DataContext>
<MyViewModel />
</MyView.DataContext>
and
public void BringSomethingNew()
{
var myView = new View();
(myView.DataContext as ViewModel).Model = myModel;
UseMyView();
}
Another benefit with this approach is that the ViewModel is created once, with the same path at design and run time, so you create less objects and save GC efforts. I find this elegant.
With regards to the setters, the design data will still work if you make them private, like:
public string MyProp { get; private set; }
Ok, customize it to manage NotifyPropertyChange at your convenience, but you've got the idea.
Now, I don't have yet a solution to manage ObesrvableCollections (I face the same problem, although putting multiple values in XAML sometimes work... ???), and yes, I agree that you have to manage the case when the properties are not set, like setting default values in the constructor.
I hope this helps.
I too have worked with NUnit testing with WPF and MVVM implementation. However, my version is reversed from yours. You are creating the view first, then creating the model to control it.
In my version, I create the MVVM model FIRST and can unit test it till the cows come home and not worry about any visual design... if the model is broken, so too will the visual implementation.
in my MVVM model, I have a method to "GetTheViewWindow". So, when I derive from my MVVM baseline, each view model has its own view its responsible for. So via a virtual method, each instance will do its own new view window when being applied for production.
public class MyMVVMBase
{
private MyViewBaseline currentView;
public MyMVVMBase()
{ // no parameters required }
public virtual void GetTheViewWindow()
{ throw new exception( "You need to define the window to get"; ) }
}
public class MyXYZInstanceModel : MyMVVMBase
{
public override void GetTheViewWindow()
{
currentView = new YourActualViewWindow();
}
}
Hope this helps as an alternative to what you are running into.
Relatively new to patterns, let me straight away show an example in the context of WinForms.
I have a basic MVP Passive View structure, which one should I go ahead with:
public partial class UserView : Form, IUserView
{
public event EventHandler Save;
public UserView()
{
InitializeComponent();
new UserPresenter(new UserModel(), this);
}
}
public class UserPresenter
{
public UserPresenter(IUser model, IUserView view)
{
view.Save += (sender, e) => model.Save();
}
}
or
public partial class UserView : Form, IUserView
{
public event EventHandler Save;
public UserView()
{
InitializeComponent();
new UserPresenter(this);
}
}
public class UserPresenter
{
public UserPresenter(IUserView view)
{
var model = new UserModel();
//assuming I have the logic to bind property values from View to Model
view.Save += (sender, e) => model.Save();
}
}
My questions are:
1) Who should know of the concrete instance of model User, View or Presenter?
2) What will be the benefit in that case?
3) Suppose my Model is never dependent on the View. In that case what's wrong if View knows Model? After all UserView is made to present UserModel isn't it?
4) If Presenter should interact with only interfaces of Model and View, then to call model.Save in Save eventhandler, where do I get the concrete instance of Model from?
There are two duplicate questions here and here, but they aren't exactly dealing with my scenario I guess..
Strictly speaking, you should have the following rules:
Model does not know the View or the Presenter.
View does not know the Model or the Presenter.
Presenter knows both Models and Views, but only through their interfaces.
The Presenter coordinates all communication between the Model and the View, typically by handling events that are raised by the View. So to answer your questions:
1) Who should know of the concrete instance of model User, View or Presenter?
Ideally, neither. The Presenter should be communicating with UserModel through an IUserModel interface. The concrete instance is injected into the Presenter (e.g. through its constructor).
2) What will be the benefit in that case?
The primary benefit is for automated unit testing. You can inject mock Models or Views to test units in isolation.
3) Suppose my Model is never dependent on the View. In that case what's wrong if View knows Model? After all UserView is made to present UserModel isn't it?
There's nothing inherently wrong with it. There are variations of MVP that support direct communication from the View to the Model, typically to take advantage of data binding. You lose some testability in exchange for not having to write the binding code from scratch.
4) If Presenter should interact with only interfaces of Model and View, then to call model.Save in Save eventhandler, where do I get the concrete instance of Model from?
Depedency injection, such as the simplified example shown below.
public class SamplePresenter
{
public SamplePresenter(ISampleModel model, ISampleView view)
{
view.Saved += (sender, e) => model.Save();
}
}
public interface ISampleModel
{
void Save();
}
public interface ISampleView
{
void Show();
event EventHandler Saved;
}
public class Program
{
[STAThread]
static void Main()
{
ISampleModel model = new SampleModel();
ISampleView view = new SampleView();
SamplePresenter presenter = new SamplePresenter(model, view);
view.Show();
}
}
What's wrong if view knows model? After all UserView is made
specifically for UserModel isnt it?
Nothing. It's accepted practice in the Supervising Controller variant of the MVP pattern. The view interacts directly with the model for simple operations while more complex operations are marshalled throught the presenter. While in Passive View, everything goes through the presenter.
Additionally, see Jeremy Miller's Build your own CAB series to get a better idea on the differences between the two approaches: Supervising Controller and Passive View.
The Presenter should know about the Model, the View should not. A presententation layer is a good idea in many user interface applications. A presentation layer is simply an adapter. It presents an interface that's easy for a user interface layer to use (i.e., it presents lots of events, bindable properties, and so on) while obscuring the underlying data layer. This makes the data layer easier to re-use.
EDIT
So why can't the view just talk to the model directly? It certainly can. The problem is that there is usually an impedence mismatch between the model and the view. In other words, the programming interface that's natural for the view to use does not match the interface that's natural for the model to expose. If you adapt the model to suit the view's needs, then you end up creating a strong coupling between the model and the particular type of interface you're using.
For example, your app might be a GUI app today, but what if tomorrow you're asked to produce a version for the cloud? The events and bindable properties that are helpful for Winforms will just get in the way when you try to switch to WCF Rest. If you use a presentation layer, then adapting your code to the new environment will be much easier.
If it's not too much for your introduction to presentation patterns, I'd urge you to take a look at the Presenter-first variant of MVP.
In this variant, and providing an answer to your question, the presenter knows both the model and view but only via interfaces. Neither the view, nor the model know of each other. The presenter co-ordinates each via events and methods.
http://atomicobject.com/pages/presenter+first
http://spin.atomicobject.com/2008/01/30/presenter-first-get-your-triads-talking/
Example:
Class Presenter {
private IModel model;
private IView view;
void Presenter(IModel model, IView view) {
_model = model;
_view = view;
}
void Initialise() {
// Attach handler to event view will raise on save
_view.OnSave += HandleViewSave();
}
void HandleViewSave(){
_model.Save(_view.GetStuffToSave());
}
}
Very basic example but illustrates the point. The presenter is merely a conduit for communication between the view and model.
Creating the presenter can be done with Poor Man's DI or a proper container:
Presenter p = new Presenter(new CustomerModel(), new CustomerForm());
Note that AtomicObject recommend no reference to presenter, so it actually looks like this:
new Presenter(existingCustomerModel, existingCustomerForm);
existingCustomerModel.Initialise();
The fact that the model and view have scope means the presenter also stays in scope via its references... clever.
Greetings! Am enjoying using MVVM light -great framework - has made my life much easier, and has removed a number of barriers that were proving difficult to overcome....
Question:
I am attempting to setup a custom dialog box for editing messages users send to each other. I am attempting to construct a silverlight custom dialog box using the ChildWindow object using the MVVM framework.
Was wondering if there were any suggestions as to how this might be accomplished
Following the dialog MVVM sample code I found here: http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=209338 I got stuck because the ChildWindow dialog object in Silverlight is async, and has a different Result class.
So - the Basic idea I have now is using the view model of the class (in this case the Matrix.MessageViewModel) to create an instance of the custom dialog box, send it through the Messenger.Send<>, process the registered message in the view to display the dialog, then have the ChildWindow dialog box's Save button handler fire a Messenger.Send with the modified contents that is then stored using the Save method on the viewmodel...
Seems a bit round-about - so wanted to make sure there wasn't a cleaner way....
Relevant code bits:
view model:
messageDialogBox = new MessageEditorDialog(
selectedMessage, this.SelectedSiteId, this.LoggedOnEmployee.Id, this.Projects);
DialogMessage editMessage = new DialogMessage(
this, messageDialogBox,"Edit Message", DialogMessageCallback);
Messenger.Default.Send(editMessage);
View:
public ViewHost()
{
InitializeComponent();
Loaded += new RoutedEventHandler(ViewHost_Loaded);
if (!ViewModelBase.IsInDesignModeStatic)
{
// Use MEF To load the View Model
CompositionInitializer.SatisfyImports(this);
}
ApplicationMessages.IsBusyMessage.Register(this, OnIsBusyChange);
Messenger.Default.Register<DialogMessage>(this, msg => ShowDialog(msg));
}
private void ShowDialog(DialogMessage msg)
{
MessageEditorDialog myDialog = (MessageEditorDialog) msg.Target;
myDialog.Show();
}
Dialog Save:
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
Messenger.Default.Send<Message>(
this.MessageItem, CommandMessages.MessageTypes.MessageSave);
}
This ties back into the ViewModel, that has a Messenger.Default.Register<> watching for the CommandTypes.MessageSave which routes the resulting MessageItem to the model for storage.....
That's pretty darn close to what I'd do, except there are a couple of things I do differently.
I'd have a view model for my dialog view, and move the messaging logic to it rather than the view's code behind.
I'd use a Save command in my view model, and bind the ButtonSave to that command. That moves the save logic to the view model instead of the code behind of your view.
You're using a different message when the save button is clicked. Also, you're not using the DialogMessage's callback. Assuming you change to using a Save command, you could save the message in a private member in the view model, then use message's callback when the user saves.
You may want to think about re-using the dialog view, or ensuring that the view is being cleaned up correctly so you don't end up with a memory leak.
Here's the changes I'd make to your view model following suggestions 2 & 3.
public class MessageEditorDialogViewModel : ViewModelBase
{
private DialogMessage _dialogMessage;
public RelayCommand SaveCommand { get; private set; }
public DialogMessage Message { get; set; }
public MessageEditorDialogViewModel()
{
SaveCommand = new RelayCommand(SaveCommandExecute);
}
private SaveCommandExecute()
{
Message.Execute();
}
}
I am using MVVM Light toolkit in my WPF application. I would like to know what is the best approach for opening a new window from an existing window. I have got this MainViewModel, which is responsible for MainWindow of my application. Now in the MainView, on a button click, I would like to open a second window on top of it. I have got RelayCommmand binded to the Button's Command. In the RelayCommand's method, I can create a new window object and simply call Show(), something like this:
var view2 = new view2()
view2.Show()
but I don't think the ViewModel should be responsible for creating the new view2 object. I have read this post WPF MVVM Get Parent from VIEW MODEL where Bugnion has suggested to pass message to the view1 from the viewmodel1 and then view1 should create the new view2. But I am not sure what does he actually mean by passing the message to the view1? How should the view1 handle the message? In it's code behind or what?
Regards,
Nabeel
Passing a message from ViewModel1 to View1 means to use the messaging capabilities in the MVVM Light Toolkit.
For example, your ViewModel1 could have a command called ShowView2Command, then it would send a message to display the view.
public class ViewModel1 : ViewModelBase
{
public RelayCommand ShowView2Command { private set; get; }
public ViewModel1() : base()
{
ShowView2Command = new RelayCommand(ShowView2CommandExecute);
}
public void ShowView2CommandExecute()
{
Messenger.Default.Send(new NotificationMessage("ShowView2"));
}
}
View1 would register to receive messages in its code behind and display View2 when it receives the correct message.
public partial class View1 : UserControl
{
public View1()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowView2")
{
var view2 = new view2();
view2.Show();
}
}
}
Why do you go this route? Its simple. If you replace your button with a toggleButton, or a hyperlink, or any other number of button-like controls, you don't need to update your "code behind" - its a basic principle of the MVVM pattern. In your new toggleButton (or whatever), you still end up binding to the same exact Command.
For example, I'm creating a project for a client who wants to have 2 UI's - one is going to be fundamentally different in every way, in terms of presentation. Horizontal tabs vs Vertical RadPanelBar (think Accordion) for navigation. Both of these views can point to the same viewModel - when a user clicks the Work Order tab in View 1, it fires the same "WorkOrderCommand" that's fired in the Work Order Header in the panel bar.
In a code-behind model, you'd have to code two separate events. Here you only have to code one.
Furthermore, it allows a designer using Blend to create any layout they want. As long as they have the hooks (EventToCommand control) in place, myself (as a developer) couldn't care less what the final product looks like.
Loose coupling is incredibly powerful.
You can do in this way like you need to create some events and register those in view and call these in view model.and open that pop up window.
Like This example
public class Mainclass : MainView
{
public delegate abc RegisterPopUp(abc A);
public RegisterPopUp POpUpEvent ;
public RelayCommand ShowCommand { private set; get; }
public void ShowCommand()
{
ShowCommand("Your parameter");
}
}
inside the view MainView mn=new MainView();
Register the event here like thake mn.POpUpEvent += than click on tab button double time
and in registers popup method right the code for opening the pop up window.
Unless I am missing the point here - if I were to use the code behind, then why not directly implement button_click event and open the second view?
What Bugnion seems to be suggesting is view1 -> button click -> relay command -> viewmodel1 -> message -> view1 -> view1.cs -> open view 2.
You are going to sacrifice testability anyhow by writing code-behind, so why take such a long route?
You can abstract the view specific features into services using generic interface. In the view layer you can provide concrete instances of these services and build view models using the IoC container and Dependency Injection technique.
In your case you can build an interface IWindowManager or something similar which has the required method. This can be implmented in your view layer. I wrote a small blog post recently demonstrating how to abstract the dialog behaviour out of view model. Similar apporach can be used for any user interface related service like Navigation, MessageBoxes etc.
This link might be helpful for you http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html
Many people also use the approach of firing events from view models which are subscribed on the view.cs file and from there the MessageBox or any other UI related action is performed. I personally like the approach of injecting services because then you can provide multiple implementations of the same service. A simple example would be how navigation is handled in Silverlight and Windows Phone 7 applications. You can use the same view model but inject different implementations of the Navigation service based on the application type.
I find the best way to approach this, is opening and closing the window from the ViewModel. As this link suggests,
Create a DialogCloser class
public static class DialogCloser
{
public static readonly DependencyProperty DialogResultProperty = DependencyProperty.RegisterAttached("DialogResult", typeof(bool?), typeof(DialogCloser), new PropertyMetadata(DialogResultChanged));
private static void DialogResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null) window.Close();
}
public static void SetDialogResult(Window target, bool? value)
{
target.SetValue(DialogResultProperty, value);
}
}
Create a Base ViewModel inheriting from GalaSoft.MvvmLight.ViewModelBase with there additional members. Once done, use this viewmodel as base for other viewmodels.
bool? _closeWindowFlag;
public bool? CloseWindowFlag
{
get { return _closeWindowFlag; }
set
{
_closeWindowFlag = value;
RaisePropertyChanged("CloseWindowFlag");
}
}
public virtual void CloseWindow(bool? result = true)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
CloseWindowFlag = CloseWindowFlag == null ? true : !CloseWindowFlag;
}));
}
In the view, Bind the DialogCloser.DialogResult dependency property with the CloseWindowFlag property in the base viewmodel.
Then you can open/close/hide the window from the viewmodel.
Can someone explain how the mediator pattern works with multiple instances.
My code in the view:
public MyView() {
Mediator.Register("CloseWindow",()=>Close());
}
and in the ViewModel:
public SomeMethod() {
Mediator.Notify("CloseWindow");
}
This works find as long as there is only one instance of the View - ViewModel pair.
How do I solve it with multiple instances?
I use an alternative solution. MyView implements an interface IMyView which contains the Close method. The MyViewModel object associates the View and so it can call the Close method through the interface.
If you are interested in a concrete example then you might have a look at:
WPF Application Framework (WAF)
I don't know how your particular implementation of the mediator pattern works, but in mine you can send more information than just strings.
For example:
public MyView() {
Mediator.Register<CloseWindowMessage>(message =>
{
if (message.ViewModel == DataContext) Close();
});
}
and in the ViewModel:
public SomeMethod() {
Mediator.Notify(new CloseWindowMessage(this));
}
In this example, the ViewModel passes itself as a parameter to the view. The view can then check that the message is being sent from its view model.