C# 需要澄清MVP模式中的演示者应该知道什么

C# 需要澄清MVP模式中的演示者应该知道什么,c#,winforms,mvp,C#,Winforms,Mvp,我正在尝试将WindowsForm重构为MVP模式。该应用程序是一个平铺编辑器。表单有一个自定义控件,我在其中显示tilemap(TileDisplay)。从文件加载贴图后,我调用名为“AdjustHScrollBar”的方法将水平滚动条重新调整为tilemap大小。我不是100%确定如何根据MVP划分方法。 首先是原始的无MVP方法: private void AdjustHScrollBar() { if (tileMap.GetWidthInPixels() > tileDi

我正在尝试将WindowsForm重构为MVP模式。该应用程序是一个平铺编辑器。表单有一个自定义控件,我在其中显示tilemap(TileDisplay)。从文件加载贴图后,我调用名为“AdjustHScrollBar”的方法将水平滚动条重新调整为tilemap大小。我不是100%确定如何根据MVP划分方法。 首先是原始的无MVP方法:

private void AdjustHScrollBar()
{
    if (tileMap.GetWidthInPixels() > tileDisplay.Width)
    {
        hTileScrollBar.Visible = true;
        hTileScrollBar.Minimum = 0;
        hTileScrollBar.Maximum = tileMap.GetWidth();
    }
    else
    {
        hTileScrollBar.Visible = false;
    }
}
这是在演示者中使用MVP后的方法:

private void AdjustHScrollBar()
{
    if (mainFormModel.TileMap.GetWidthInPixels() > mainFormView.GetTileDisplayWidth())
    {
        mainFormView.EnableHScrollBar(mainFormModel.TileMap.GetWidth());
    }
    else
    {
        mainFormView.DisableHScrollBar();
    }
}
public interface ITileMapView
{
    event EventHandler<string> TileMapFileLoaded;
    void OnTileMapLoaded(TileMapModel model);
}

public class TileMapPresenter
{
    private readonly ITileMapView view;

    public TileMapPresenter(ITileMapView view)
    {
        this.view = view;
        view.TileMapFileLoaded += OnTileMapFileLoaded;
    }

    private void OnTileMapFileLoaded(object sender, string filename)
    {
        // Parse data from file
        // Populate model

        // Tell view
        view.OnTileMapLoaded(model); //Implement the 'AdjustHScrollBar' logic in the view
    }
}

视图不知道演示者。我的问题是演示者是否应该知道视图的控件。在我的实现中,它没有-这就是GetTileDisplayWidth、EnableHScrollBar和DisableHScrollBar-方法的原因。好吧,这是正确的方法,但是如果我必须从视图中为我需要的每个属性创建一个方法,那么这似乎是一个很大的工作。对于垂直滚动条,我基本上有“相同”的代码,例如(这是重新调整滚动条的6种方法)。

演示者层的目的是能够与
视图
层进行通信,而不知道视图的具体情况,即与大小、颜色有关的任何内容,它是什么类型的视图或任何其他属性

通常,
presenter类
将在其构造函数中获取
视图对象
。理想情况下,您可以在视图上使用
Adjust
方法,演示者可以直接调用它,更理想的情况是,您可以通过界面而不是直接查看类来执行此操作

在您的代码中,您正在访问视图的所有属性,然后试图通过presenter对它们进行操作,除非您对业务逻辑有某种依赖性,否则您不必这样做。因此,您可以在
视图
层上执行整个操作,然后从
演示者
层调用它


MVP涉及大量代码,这是您必须接受的权衡

演示者层的要点是能够与
视图
层进行通信,而不知道视图的细节,即与大小、颜色、视图类型或任何其他属性有关的内容

通常,
presenter类
将在其构造函数中获取
视图对象
。理想情况下,您可以在视图上使用
Adjust
方法,演示者可以直接调用它,更理想的情况是,您可以通过界面而不是直接查看类来执行此操作

在您的代码中,您正在访问视图的所有属性,然后试图通过presenter对它们进行操作,除非您对业务逻辑有某种依赖性,否则您不必这样做。因此,您可以在
视图
层上执行整个操作,然后从
演示者
层调用它


MVP涉及大量代码,这是您必须接受的权衡

我会在演示者中执行以下操作:

private void AdjustHScrollBar()
{
    if (mainFormModel.TileMap.GetWidthInPixels() > mainFormView.GetTileDisplayWidth())
    {
        mainFormView.EnableHScrollBar(mainFormModel.TileMap.GetWidth());
    }
    else
    {
        mainFormView.DisableHScrollBar();
    }
}
public interface ITileMapView
{
    event EventHandler<string> TileMapFileLoaded;
    void OnTileMapLoaded(TileMapModel model);
}

public class TileMapPresenter
{
    private readonly ITileMapView view;

    public TileMapPresenter(ITileMapView view)
    {
        this.view = view;
        view.TileMapFileLoaded += OnTileMapFileLoaded;
    }

    private void OnTileMapFileLoaded(object sender, string filename)
    {
        // Parse data from file
        // Populate model

        // Tell view
        view.OnTileMapLoaded(model); //Implement the 'AdjustHScrollBar' logic in the view
    }
}
公共接口ITileMapView { 事件事件处理程序TileMapFileLoaded; void OnTileMapLoaded(TileMapModel模型); } 公共类TileAppresenter { 私有只读ITileMapView视图; 公共TileAppresenter(ITileMapView视图) { this.view=视图; view.TileMapFileLoaded+=OnTileMapFileLoaded; } 私有void OnTileMapFileLoaded(对象发送方,字符串文件名) { //解析文件中的数据 //填充模型 //告诉视图 view.OnTileMapLoaded(model);//在视图中实现“AdjustHScrollBar”逻辑 } }
演示者知道何时以及如何获取数据,以及如何解释数据。您不应该让演示者参与任何视图特定的逻辑。

我会在演示者中执行以下操作:

private void AdjustHScrollBar()
{
    if (mainFormModel.TileMap.GetWidthInPixels() > mainFormView.GetTileDisplayWidth())
    {
        mainFormView.EnableHScrollBar(mainFormModel.TileMap.GetWidth());
    }
    else
    {
        mainFormView.DisableHScrollBar();
    }
}
public interface ITileMapView
{
    event EventHandler<string> TileMapFileLoaded;
    void OnTileMapLoaded(TileMapModel model);
}

public class TileMapPresenter
{
    private readonly ITileMapView view;

    public TileMapPresenter(ITileMapView view)
    {
        this.view = view;
        view.TileMapFileLoaded += OnTileMapFileLoaded;
    }

    private void OnTileMapFileLoaded(object sender, string filename)
    {
        // Parse data from file
        // Populate model

        // Tell view
        view.OnTileMapLoaded(model); //Implement the 'AdjustHScrollBar' logic in the view
    }
}
公共接口ITileMapView { 事件事件处理程序TileMapFileLoaded; void OnTileMapLoaded(TileMapModel模型); } 公共类TileAppresenter { 私有只读ITileMapView视图; 公共TileAppresenter(ITileMapView视图) { this.view=视图; view.TileMapFileLoaded+=OnTileMapFileLoaded; } 私有void OnTileMapFileLoaded(对象发送方,字符串文件名) { //解析文件中的数据 //填充模型 //告诉视图 view.OnTileMapLoaded(model);//在视图中实现“AdjustHScrollBar”逻辑 } }
演示者知道何时以及如何获取数据,以及如何解释数据。您不应让演示者参与任何视图特定的逻辑。

我在演示者中这样做的原因是因为它取决于模型(tilemap大小)。我在演示者中这样做的原因是因为它取决于模型(tilemap大小)。