这是我第一次尝试让MVP与WinForms一起工作。我确实有一个更大的项目。但是,在这里我对WinForms MVP示例进行了非常简单的尝试。我只有一个模型,一个表单和两个视图。 Presenter连接在Program.cs中。一切都运作。但是,使用一个特定的用户控件,我似乎无法将其余的业务逻辑重构为Presenter。我试图做一个很容易修改为示例项目的例子。我真的不是在寻找简单的工作,而是在寻找“佳能”的答案,如果有这样的话。您可以提供的任何帮助或建议都值得赞赏。即使朝着正确的方向努力也会有很大的帮助。
我的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);
}
}
我的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;
}
现在如何将此逻辑提取回Presenter? MVP模式(根据Pluralsight的 - Windows窗体最佳实践)声明视图不应该关心它正在显示的数据。例如关注点分离。但我希望我的视图在模型更改时更新。
答案 0 :(得分:0)
它可能不是佳能,但是,这就是我处理它的方式。建设性批评仍然受到欢迎。简单地说'只是称我为一个没有思想的白痴,或者告诉我我做了什么或做得不好的事情也是如此。
我修改过的演示者:
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);
}
}
我的修改后的用户控制(查看):
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;
}