c#-MVP被动视图-将视图数据和模型数据分开

我已经使用被动视图模式实现了MVP三元组-即视图仅包含简单的getter和setter.但是,我很难分离视图数据和模型数据.特别是在处理视图状态更改时.

三重轴用于使用户能够从列表中选择零件.零件清单由模型提供,每个零件均由唯一的ID唯一标识.

可以说部分看起来像这样:

class Part
{
    int ID; // this code uniquely identifies the part within the model
    String partCode;
    String description;
    double voltage;
}

该视图向用户显示列表,并允许他们选择零件

该列表显示在DataGridView中,并通过单击dataGridView中的一行来选择零件.

该ID既不显示给用户,也不显示给用户,因此该模型创建一个仅包含partCode和说明的数据表.演示者将此DataTable分配给视图上的属性,该视图映射到DataGridView的DataSource属性.

class Presenter
{
    IView _view;
    IModel _model;

    //...///

    _view.Data = _model.GetFilteredData();
}

class Model
{
    public DataTable GetFilteredData()
    {
        // create a DataTable with the partCode and Description columns only
        // return DataTable
    } 
}

class View  //winform
{
      public DataTable Data
      {
          set 
          {
              this.dataGridView.Source = value;
          }
      }
}

到现在为止还挺好.该视图在DataGridView中分配过滤后的数据.

我遇到的问题是退还用户选择的零件.

该视图不知道唯一ID,因为它不会显示,并且其他信息也不能保证是唯一的-因此无法唯一地标识所选零件.

本质上,我试图将视图数据(选定的行)转换为模型数据(选定的零件),而没有一个组件使用其他数据.

到目前为止,我有以下解决方案:

1)向该视图传递一个包含ID的DataTable,然后对其进行过滤以使其不显示给用户.这样就很容易返回所选行的ID.这里的问题是我现在使用未经测试的逻辑(显示的过滤)污染了视图.

2)视图返回行索引,并且模型将该索引与原始数据中的行匹配.这将意味着确保视图中的顺序永不改变,而这可能会限制视图如何显示(和操作)数据.这也会污染视图数据(行索引)的模型.

    public int RowIndexSelected { get; private set; }

    //...//

    private void gridParts_CellEnter(object sender, DataGridViewCellEventArgs e)
    {
        if (SelectedPartChangedEvent != null)
        {
            RowIndexSelected = e.RowIndex;

            SelectedPartChangedEvent();            
        }
    }

3)(2)的变体.创建一个适配器对象,使其位于演示者和视图之间.将行移至ID转换代码,从模型到适配器.演示者然后处理dataGridAdapters部件更改事件.

    public PartSelectDataGridAdapter(IPartSelectView view, PartCollection data)
    {
        _view = view;
        _data = data;

        _view.SelectedPanelChangedEvent += HandleSelectedPartChanged;
    }

    void HandleSelectedPartChanged()
    {
        int id = _data[_view.RowIndexSelected].ID;

        if (SelectedPartChanged != null)
        {
            SelectedPartChanged(id);
        }
    }

目前,由于3是可测试的,因此我正在学习3,将逻辑置于视图之外,并将数据置于模型和演示者之外.

您将如何解决-是否有更好的解决方案?

解决方法:

The ID is not to be displayed to the
user and neither is the voltage,
therefore the model creates a
DataTable that contains just the
partCode and description.

一个简单的解决方案:在数据表和hide it in in the datagrid view中创建一个ID列.

上一篇:C#-WndProc处理程序效率低下


下一篇:CodeGo.net> C#-MailMessage的问题/混乱