【问题标题】:How can I strip out logic from a UserControl (View) to the Presenter如何将用户控件(视图)中的逻辑剥离到演示者
【发布时间】:2015-09-23 18:04:25
【问题描述】:

这是我第一次尝试让 MVP 与 WinForms 一起工作。我确实有一个更大的项目。但是,在这里我对 WinForms MVP 示例进行了非常简单的尝试。我只有一个模型、一个表单和两个视图。演示者在 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 Forms Best Practices)声明视图不应该关心它显示的数据。例如关注点分离。但我希望我的视图在模型更改时更新。

【问题讨论】:

    标签: c# winforms mvp


    【解决方案1】:

    这可能不是佳能,但我是这样处理的。建设性的批评仍然非常受欢迎。简单地说,只是称我为无思想的白痴或告诉我我做错了什么也是找到的。

    我修改后的 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);
        }
    }
    

    我修改的用户控件(视图):

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 2016-12-18
      • 1970-01-01
      相关资源
      最近更新 更多