San*_*ndy 7 c# data-binding mvp winforms
我有一个在MVP中实现的WinForms应用程序.我的表单有一个TextBox,我想将其Text属性数据绑定到Model中的属性.我不想在视图中引用模型.
在谷歌搜索后,我发现通过耦合模型和视图进行数据绑定是一个坏主意.我的样品初始化Model,View并且Presenter是如下.
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()
    {
    }
}
目前我已经为每3个项目Model,View和Presenter.View参考Presenter并Presenter参考Model.任何人都可以指导我如何形成数据绑定到控件View到属性Model?
编辑
我知道在Grid中做的事情.我们可以在演示者中将Datasource网格的属性分配给List(或类似的),如:
_view.DataSource = _model.ListOfEmployees;
这将反映ListOfEmployees模型中更改时UI中的值.但是什么TextBox暴露Text财产呢?我怎样才能在MVP架构中绑定它?
IAb*_*act 10
我的建议是将视图和模型封装在Presenter中.这意味着给定视图的专用Presenter(在大多数情况下).在我看来,这很好用,因为大多数模型无论如何都会有所不同.
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;
    }
}
在IView中,公开控件或控件的数据源属性:
interface IView {
    object GridDataSource { get; set; }
}
添加到您的Presenter的一些方法:
void SetGridDatasource() {
    view.GridDatasource = model.SomeBindableData;
}
查看实施:
public object GridDatasource {
    get { return myGridView.DataSource; }
    set { myGridView.DataSource = value; }
}
注意:
 
代码段未经测试,建议作为起点.  
更新注释:
INotifyPropertyChanged是一种非常有价值的机制,用于更新IView和之间的属性IModel.
大多数控件都具有某种绑定功能.我建议尽可能使用这些DataBinding方法.只需通过IView公开这些属性,然后让Presenter将这些绑定设置为IModel属性.
说明:
如果要将文本框数据绑定到模型的底层属性:
第一:像许多其他状态一样,包含属性的任何内容都必须实现INotifyPropertyChanged接口,以便在更改object属性时触发必要的事件以通知视图更改.在这方面,我将使用viewmodel作为模型的属性来封装您希望将视图数据绑定的特定属性.
第二:您的IView将包含View必须实现的viewmodel属性.
第三:您的View将实现IView属性,viewmodel对象上只有一个set访问器,用于将每个文本框数据绑定到dto属性.请注意,在下面的示例中,我如何在视图加载后再次手动设置文本框.现在,当底层模型的viewmodel属性更改时,将更新textbox.text值.这适用于两种方式(双向数据绑定).使用用户输入编辑文本框将更改基础模型的dto属性值.
第四:您的演示者只会在视图加载时将IView的属性设置为Model的属性一次.
示例:请记住,这是一个非常简化的粗略示例,并且没有像OP正在使用的任何模型抽象,但应该为Winforms MVP中的文本框数据绑定提供一个良好的起点.我将在生产应用程序中更改的另一件事是使Model无状态并将viewmodel(person)移动到演示者中.
//VIEWMODEL
public class Person : INotifyPropertyChanged
{
    string _firstName;
    string _lastName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if(value != _firstName)
            {
                _firstName = value;
                NotifyPropertyChanged("FirstName");
            }
        }
    }
    public string LastName
    {
        get { return _lastName; }
        set
        {
            if (value != _lastName)
            {
                _lastName = value;
                NotifyPropertyChanged("LastName");
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}
//MODEL
class Model
{
    Person _person;
    public Person Person { get { return _person; } }
    public Model()
    { 
        //Set default value
        _person = new Person(){ FirstName = "Test", LastName = "Subject" };
    }
    public void ChangePerson()
    {
        //When presenter calls this method, it will change the underlying source field and will reflect the changes in the View.
        _person.FirstName = "Homer";
        _person.LastName = "Simpson";
    }
}
//PRESENTER
class Presenter
{
    readonly View _view;
    readonly Model _model;
    public Presenter(View view)
    {
        _view = view;
        _model = new Model();
        _view.OnViewLoad += Load;
        _view.OnChangePerson += ChangePerson;
    }
    private void Load()
    {
        _view.Person = _model.Person;
    }
    private void ChangePerson()
    {
        _model.ChangePerson();
    }
}
//IVIEW
interface IView
{
   Person person { set; }
   event Action OnViewLoad;
   event Action OnChangePerson;
}
//VIEW
public partial class View : IView
{
     public View()
     {
         Presenter presenter = new Presenter(this); 
         this.Load += (s, e) => OnViewLoad(); //Shorthand event delegate
         this.btnChange.Click += (s, e) => OnChangePerson(); //Shorthand event delegate
     }
     public event Action OnViewLoad;
     public event Action OnChangePerson;
     public Person person
     {   //This is how you set textbox two-way databinding
         set
         {
               //Databinding syntax: property of control, source, source property, enable formatting, when to update datasource, null value
               txtFirstName.DataBindings.Add(new Binding("Text", value, "FirstName", true, DataSourceUpdateMode.OnPropertyChanged, string.Empty));
               txtLastName.DataBindings.Add(new Binding("Text", value, "LastName", true, DataSourceUpdateMode.OnPropertyChanged, string.Empty)); 
         }
     }
}
| 归档时间: | 
 | 
| 查看次数: | 7168 次 | 
| 最近记录: |