I have a WinForms application implemented in MVP. My form has a TextBox
and I want to databind its Text
property to a property in the Model. I don't want to refer to the Model in the View.
After searching in Google, I found that databinding by coupling Model and View is a bad idea. My sample initialization of Model
, View
and Presenter
is as follows.
class View : Form, IView
{
public View()
{
InitializeComponent();
new Presenter(this);
}
}
class Presenter
{
public Presenter(IView) : this.Presenter(this, new Model())
{
}
public Presenter(IView view)
{
}
}
class Model : IModel
{
public Model()
{
}
}
At present I have 3 projects each for Model
, View
and Presenter
. View has reference to Presenter
and Presenter
has reference to Model
. Can anyone guide me how to form a databinding to a control in View
to a property in Model
?
EDIT
I know to do the things in Grid. We can assign Datasource
property of grid to a List
(or something similar) in presenter like:
_view.DataSource = _model.ListOfEmployees;
This will reflect the value in UI when ListOfEmployees
changes in the Model. But what about a TextBox
which exposes a Text
property? How can I bind that in MVP architecture?
My recommendation is to encapsulate the View and Model in the Presenter. This means a specialized Presenter (in most cases) for a given View. In my opinion, this works out well since most Models will be different anyway.
class Presenter {
readonly IView view;
readonly IModel model;
public Presenter() {
// if view needs ref. to presenter, pass into view ctor
view = new View(this);
model = new Model();
}
// alternatively - with the model injected - my preference
public Presenter(IModel Model) {
// if view needs ref. to presenter, pass into view ctor
view = new View(this);
model = Model;
}
}
In your IView, expose a control or control's data source property:
interface IView {
object GridDataSource { get; set; }
}
Add to your Presenter some method:
void SetGridDatasource() {
view.GridDatasource = model.SomeBindableData;
}
View implementation:
public object GridDatasource {
get { return myGridView.DataSource; }
set { myGridView.DataSource = value; }
}
Note:
Code snippets are untested and recommended as a starting point.
Update to comments:
INotifyPropertyChanged
is a very valuable mechanism for updating properties between IView
and IModel
.
Most controls do have some sort of binding capability. I would recommend using those DataBinding methods whenever possible. Simply expose those properties through IView and let the Presenter set those bindings to the IModel properties.