我如何剥离从UserControl (View)到Presenter的逻辑?



这是我第一次尝试让MVP与WinForms一起工作。我脑子里有个更大的项目。然而,这里我有一个非常简单的尝试在WinForms MVP的例子。我只有一个模型、一个表单和两个视图。演示器被连接在Program.cs中。一切都行得通。然而,对于一个特定的用户控件,我似乎无法将其余的业务逻辑重构到演示器中。我试图使一个例子,很容易修改为一个演示项目。我真的不是在寻找简单地让它工作,而是我在寻找"经典"的答案,如果有这样的事情。你能提供的任何帮助或建议,我都很感激。即使朝正确的方向推一把也会有很大的帮助。

我MainFormPresenter

:

internal class MainFormPresenter
{
    private readonly SimpleContext _context = new SimpleContext();
    private readonly IMainFormView _mainFormView;
    private readonly IPeopleListView _peopleListView;
    private readonly IPersonInfoView _personInfoView;
    public MainFormPresenter(IMainFormView mainFormView)
    {
        _peopleListView = mainFormView.PeopleListView;
        _personInfoView = mainFormView.PersonInfoView;
        _mainFormView = mainFormView;
        mainFormView.Load += MainFormViewOnLoad;
        mainFormView.FormClosed += MainFormViewOnFormClosed;
        _peopleListView.SelectionChanged += OnSelectedNameChanged;
    }
    private void OnSelectedNameChanged(object sender, EventArgs e)
    {
        int id = _peopleListView.GetSelectedId();
        Person person = _context.People.Find(id);
        _personInfoView.SetFirstName(person.FirstName);
        _personInfoView.SetLastName(person.LastName);
        _personInfoView.SetBirthDate(person.BirthDate);
    }
    private void MainFormViewOnFormClosed(object sender, FormClosedEventArgs e)
    {
        _context.Dispose();
    }
    private void MainFormViewOnLoad(object sender, EventArgs e)
    {
        _context.People.Load();
        BindingList<Person> people = _context.People.Local.ToBindingList();
        _peopleListView.SetDataSource(people);
    }
}

My Code-Behind for My PeopleListView:

public partial class PeopleListView : UserControl, IPeopleListView
{
    private readonly BindingSource _bSource;
    public PeopleListView()
    {
        _bSource = new BindingSource();
        InitializeComponent();
    }
    public int GetSelectedId()
    {
        DataGridViewRow row = PeopleGridView.CurrentRow;
        if (row != null)
        {
            Person person = (Person)row.DataBoundItem;
            return person.PersonId;
        }
        return 0;
    }
    public void SetDataSource(BindingList<Person> people)
    {
        _bSource.DataSource = people;
        _bSource.RaiseListChangedEvents = true;
        PeopleGridView.AutoGenerateColumns = false;
        PeopleGridView.DataSource = _bSource;
    }
    private void PeopleGridView_SelectionChanged(object sender, EventArgs e)
    {
        SelectionChanged?.Invoke(new object(), new EventArgs());
    }
    public event EventHandler SelectionChanged;
}

现在我如何将这个逻辑提取回演示器?MVP模式(根据Pluralsight的- Windows窗体最佳实践)说明视图不应该关心它所显示的数据。关注点分离。但是我想让我的视图在模型改变时更新

这可能不是标准,但是,这是我如何处理它。建设性的批评仍然非常受欢迎。简单地说我是一个没有头脑的白痴,或者告诉我我做了什么或没有做对什么,也是找不到的。

我修改过的Presenter:

internal class MainFormPresenter
{
    private readonly SimpleContext _context = new SimpleContext();
    private readonly IMainFormView _mainFormView;
    private readonly IPeopleListView _peopleListView;
    private readonly IPersonInfoView _personInfoView;
    public MainFormPresenter(IMainFormView mainFormView)
    {
        _peopleListView = mainFormView.PeopleListView;
        _personInfoView = mainFormView.PersonInfoView;
        _mainFormView = mainFormView;
        _mainFormView.Load += MainFormViewOnLoad;
        _mainFormView.FormClosed += MainFormViewOnFormClosed;
        _peopleListView.SelectionChanged += OnSelectedNameChanged;
    }
    private void OnSelectedNameChanged(object sender, EventArgs e)
    {
        DataGridViewRow row = _peopleListView.GetSelectedRow();
        Person person = (Person) row.DataBoundItem;
        _personInfoView.SetFirstName(person.FirstName);
        _personInfoView.SetLastName(person.LastName);
        _personInfoView.SetBirthDate(person.BirthDate);
    }
    private void MainFormViewOnFormClosed(object sender, FormClosedEventArgs e)
    {
        _context.Dispose();
    }
    private void MainFormViewOnLoad(object sender, EventArgs e)
    {
        _context.People.Load();
        BindingList<Person> people = _context.People.Local.ToBindingList();
        BindingSource bSource = new BindingSource
        {
            DataSource = people,
            RaiseListChangedEvents = true
        };
        _peopleListView.SetDataSource(bSource);
    }
}

My Modified User Control (View):

public partial class PeopleListView : UserControl, IPeopleListView
{
    public PeopleListView()
    {
        InitializeComponent();
    }
    public DataGridViewRow GetSelectedRow()
    {
        return PeopleGridView.CurrentRow;
    }
    public void SetDataSource(BindingSource bSource)
    {
        PeopleGridView.AutoGenerateColumns = false;
        PeopleGridView.DataSource = bSource;
    }
    private void PeopleGridView_SelectionChanged(object sender, EventArgs e)
    {
        SelectionChanged?.Invoke(new object(), new EventArgs());
    }
    public event EventHandler SelectionChanged;
}

最新更新