事件冒泡和 MVP:ASP.NET

发布于 2024-12-26 10:29:02 字数 10101 浏览 2 评论 0原文

我正在尝试学习 MVP

它是在 ASP.NET 中使用 Web 表单。我有两个用户控件 CurrentTimeView.ascx 和 MonthViewControl.ascx。 CurrentTimeView 显示时间。有一个文本框可以在同一控件中添加天数。新得到的日期称为“结果日期”。单击添加天数按钮时,会引发“myBtnAddDaysClickedEvent”事件。

在 MonthViewControl 上,有一个标签显示“结果日期”的月份。目前我正在为变量“monthValueToPass”设置一个样本值(因为我不知道如何正确执行)。 如何设置monthValueToPass变量的值以使其符合MVP模型?

string monthValueToPass = "TEST";
monthPresenter.SetMonth(monthValueToPass);

期望创建易于进行单元测试且不违反MVP架构的MVP。 >

注意:虽然这是一个简单的示例,但我期待使用 MVP 和验证机制对 GridView 控件中的数据绑定进行扩展的答案。

注意:视图可以完全独立于演示者吗?

注意:这里每个用户控件都是单独的视图

注意:同一个演示者可以有多个视图(例如根据用户的权限为不同的用户提供不同的控件?)

指南

  1. 模型视图演示者 - 指南

--COMPLETE代码--

using System;
public interface ICurrentTimeView
{
    //Property of View
    DateTime CurrentTime 
    {
        set; 
    }
    //Method of View
    void AttachPresenter(CurrentTimePresenter presenter);
}

using System;
public interface IMonthView
{
    //Property of View
    string MonthName 
    {
        set; 
    }

    //Method of View
    //View interface knows the presenter
    void AttachPresenter(MonthPresenter presenter);     
}

using System;
public class CurrentTimePresenter 
{
    private ICurrentTimeView view;

    //Constructor for prsenter
    public CurrentTimePresenter(ICurrentTimeView inputView) 
    {
        if (inputView == null)
        {
            throw new ArgumentNullException("view may not be null");
        }
    }
    this.view = inputView;
}

//Method defined in Presenter
public void SetCurrentTime(bool isPostBack) 
{
    if (!isPostBack) 
    {
        view.CurrentTime = DateTime.Now;
    }
}

//Method defined in Presenter
public void AddDays(string daysUnparsed, bool isPageValid) 
{
    if (isPageValid) 
    {
        view.CurrentTime = DateTime.Now.AddDays(double.Parse(daysUnparsed));           
    }
}

using System;
public class MonthPresenter
{
    private IMonthView monthView;

    //Constructor for prsenter
    public MonthPresenter(IMonthView inputView)
    {
        if (inputView == null)
        {
           throw new ArgumentNullException("view may not be null");
        }
        this.monthView = inputView;
    }


    //Method defined in Presenter
    //How does presenter decides the required value.
    public void SetMonth(string monthValueInput) 
    {
       if (!String.IsNullOrEmpty(monthValueInput))
       {
          monthView.MonthName = monthValueInput;
       }
       else
       {

       }        
    }   
}

用户控件 1

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CurrentTimeView.ascx.cs" Inherits="Views_CurrentTimeView" %>

<asp:Label id="lblMessage" runat="server" /><br />
<asp:Label id="lblCurrentTime" runat="server" /><br />
<br />

<asp:TextBox id="txtNumberOfDays" runat="server" />
<asp:Button id="btnAddDays" Text="Add Days" runat="server" OnClick="btnAddDays_OnClick" ValidationGroup="AddDays" />

using System;
using System.Web.UI;
public partial class Views_CurrentTimeView : UserControl, ICurrentTimeView
{
   //1. User control has no method other than view defined method for attaching presenter
   //2. Properties has only set method

   private CurrentTimePresenter presenter;

   // Delegate 
   public delegate void OnAddDaysClickedDelegate(string strValue);

   // Event 
   public event OnAddDaysClickedDelegate myBtnAddDaysClickedEvent;

   //Provision for getting the presenter in User Control from aspx page.
   public void AttachPresenter(CurrentTimePresenter presenter)
   {
       if (presenter == null)
       {
         throw new ArgumentNullException("presenter may not be null");
       }
       this.presenter = presenter;
   }

   //Implement View's Property
   public DateTime CurrentTime
   {
      set
      {
        //During set of the property, set the control's value
        lblCurrentTime.Text = value.ToString();
      }
   }

   //Event Handler in User Control
   protected void btnAddDays_OnClick(object sender, EventArgs e)
   {
      if (presenter == null)
      {
         throw new FieldAccessException("presenter null");
      }

      //Ask presenter to do its functionality
      presenter.AddDays(txtNumberOfDays.Text, Page.IsValid);

      //Raise event
      if (myBtnAddDaysClickedEvent != null)
      {
        myBtnAddDaysClickedEvent(string.Empty);
      }
   }     
}

用户控件 2

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MonthViewControl.ascx.cs" Inherits="Views_MonthViewControl" %>

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Views_MonthViewControl : System.Web.UI.UserControl, IMonthView
{
   //1. User control has no method other than view defined method for attaching presenter
   //2. Properties has only set method

   private MonthPresenter presenter;

   //Provision for gettng the presenter in User Control from aspx page.
   public void AttachPresenter(MonthPresenter presenter)
   {
      if (presenter == null)
      {
         throw new ArgumentNullException("presenter may not be null");
      }
      this.presenter = presenter;
   }

   //Implement View's Property
   public string MonthName
   {
      set
      {
        //During set of the popert, set the control's value
        lblMonth.Text = value.ToString();
      }
   }

   protected void Page_Load(object sender, EventArgs e)
   {

   }    
}

ASPX 页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ShowMeTheTime.aspx.cs"      Inherits="ShowTime" %>

<%@ Register TagPrefix="mvpProject" TagName="CurrentTimeView" Src="Views/CurrentTimeView.ascx" %>

<%@ Register TagPrefix="month" TagName="MonthView" Src="Views/MonthViewControl.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>PAGE TITLE </title>
</head>
<body>
<form id="form1" runat="server">

    <mvpProject:CurrentTimeView id="ucCtrlcurrentTimeView" runat="server" 
    />
    <br />
    <br />
    <month:MonthView id="ucCtrlMonthView" runat="server" />

</form>
</body>
</html>

using System;
using System.Web.UI;

public partial class ShowTime : Page
{
    CurrentTimePresenter currentTimePresenter;
    MonthPresenter monthPresenter;

    protected void Page_Load(object sender, EventArgs e) 
    {
       HelperInitCurrentTimeView();
       HelperInitMonth();
    }

    private void HelperInitMonth()
    {
       //Create presenter
       monthPresenter = new MonthPresenter(ucCtrlMonthView);

       //Pass the presenter object to user control
       ucCtrlMonthView.AttachPresenter(monthPresenter);
    }

    private void HelperInitCurrentTimeView() 
    { 
       //Cretes presenter by passing view(user control) to presenter.
       //User control has implemented IView
       currentTimePresenter = new CurrentTimePresenter(ucCtrlcurrentTimeView);

        //Pass the presenter object to user control
        ucCtrlcurrentTimeView.AttachPresenter(currentTimePresenter);

        //Call the presenter action to load time in user control.
        currentTimePresenter.SetCurrentTime(Page.IsPostBack);

        //Event described in User Control ???? Subsribe for it.
        ucCtrlcurrentTimeView.myBtnAddDaysClickedEvent += new Views_CurrentTimeView.OnAddDaysClickedDelegate(CurrentTimeViewControl_AddButtonClicked_MainPageHandler);        
    }

    void CurrentTimeViewControl_AddButtonClicked_MainPageHandler(string strValue)
    {
       string monthValue = "l";
       monthPresenter.SetMonth("SAMPLE VALUE");
       //myGridCntrl.CurentCharacter = theLetterCtrl.SelectedLetter;
       //myGridCntrl.LoadGridValues();
    }
}

一些 MVP 讨论:

模型视图呈现器 - 指南

在 MVP 中编写验证的位置

MVP - 视图应该能够调用直接演示者方法还是应该始终引发事件?

MVP 事件或属性

MVP 中的模型 - 事件

MVP - 演示者是否应该使用会话?

为什么演示者附加到视图事件而不是视图在大多数 ASP.NET MVP 实现中调用 Presenter 方法?

公共方法或者订阅View事件

MVP 模式,演示者有多少观看次数?

MVP 和 UserControls 以及调用

ASP.NET Web 窗体 - 模型视图演示器和用户控件 control

限制违反体系结构 - asp.net MVP

表示层中的控制修改

解耦视图、演示文稿和 ASP.NET Web 表单 网络表格

I am trying to learn MVP

It is using web forms in ASP.NET. I have two user controls CurrentTimeView.ascx and MonthViewControl.ascx. The CurrentTimeView displayes time. There is a textbox to add days in the same control. The newly got date is called “resultant date”. When the button is clicked for add days, an event is raised “myBtnAddDaysClickedEvent“.

On the MonthViewControl, there is a label that shows the month of the “resultant date”. At present I am setting a sample value for the variable “monthValueToPass” (since I don’t know how to do it properly). How do I set the value for monthValueToPass variable to make it comply with MVP model?

string monthValueToPass = "TEST";
monthPresenter.SetMonth(monthValueToPass);

The expectation is to create MVP that is easy to do Unit Testing and does not violate MVP architecure.

Note: Though this is a simple example, I am expecting an answer scalablt to databinding in GridView control using MVP and validation mechanisms.

Note: Can view be totally independant of presenter?

Note: Each user control is separate views here

Note: Can there be multiple views for same presenter (like different controls for various users based on thier permisssion?)

GUIDELINES

  1. Model View Presenter - Guidelines

--COMPLETE CODE--

using System;
public interface ICurrentTimeView
{
    //Property of View
    DateTime CurrentTime 
    {
        set; 
    }
    //Method of View
    void AttachPresenter(CurrentTimePresenter presenter);
}

using System;
public interface IMonthView
{
    //Property of View
    string MonthName 
    {
        set; 
    }

    //Method of View
    //View interface knows the presenter
    void AttachPresenter(MonthPresenter presenter);     
}

using System;
public class CurrentTimePresenter 
{
    private ICurrentTimeView view;

    //Constructor for prsenter
    public CurrentTimePresenter(ICurrentTimeView inputView) 
    {
        if (inputView == null)
        {
            throw new ArgumentNullException("view may not be null");
        }
    }
    this.view = inputView;
}

//Method defined in Presenter
public void SetCurrentTime(bool isPostBack) 
{
    if (!isPostBack) 
    {
        view.CurrentTime = DateTime.Now;
    }
}

//Method defined in Presenter
public void AddDays(string daysUnparsed, bool isPageValid) 
{
    if (isPageValid) 
    {
        view.CurrentTime = DateTime.Now.AddDays(double.Parse(daysUnparsed));           
    }
}

using System;
public class MonthPresenter
{
    private IMonthView monthView;

    //Constructor for prsenter
    public MonthPresenter(IMonthView inputView)
    {
        if (inputView == null)
        {
           throw new ArgumentNullException("view may not be null");
        }
        this.monthView = inputView;
    }


    //Method defined in Presenter
    //How does presenter decides the required value.
    public void SetMonth(string monthValueInput) 
    {
       if (!String.IsNullOrEmpty(monthValueInput))
       {
          monthView.MonthName = monthValueInput;
       }
       else
       {

       }        
    }   
}

User Control 1

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CurrentTimeView.ascx.cs" Inherits="Views_CurrentTimeView" %>

<asp:Label id="lblMessage" runat="server" /><br />
<asp:Label id="lblCurrentTime" runat="server" /><br />
<br />

<asp:TextBox id="txtNumberOfDays" runat="server" />
<asp:Button id="btnAddDays" Text="Add Days" runat="server" OnClick="btnAddDays_OnClick" ValidationGroup="AddDays" />

using System;
using System.Web.UI;
public partial class Views_CurrentTimeView : UserControl, ICurrentTimeView
{
   //1. User control has no method other than view defined method for attaching presenter
   //2. Properties has only set method

   private CurrentTimePresenter presenter;

   // Delegate 
   public delegate void OnAddDaysClickedDelegate(string strValue);

   // Event 
   public event OnAddDaysClickedDelegate myBtnAddDaysClickedEvent;

   //Provision for getting the presenter in User Control from aspx page.
   public void AttachPresenter(CurrentTimePresenter presenter)
   {
       if (presenter == null)
       {
         throw new ArgumentNullException("presenter may not be null");
       }
       this.presenter = presenter;
   }

   //Implement View's Property
   public DateTime CurrentTime
   {
      set
      {
        //During set of the property, set the control's value
        lblCurrentTime.Text = value.ToString();
      }
   }

   //Event Handler in User Control
   protected void btnAddDays_OnClick(object sender, EventArgs e)
   {
      if (presenter == null)
      {
         throw new FieldAccessException("presenter null");
      }

      //Ask presenter to do its functionality
      presenter.AddDays(txtNumberOfDays.Text, Page.IsValid);

      //Raise event
      if (myBtnAddDaysClickedEvent != null)
      {
        myBtnAddDaysClickedEvent(string.Empty);
      }
   }     
}

User Control 2

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MonthViewControl.ascx.cs" Inherits="Views_MonthViewControl" %>

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Views_MonthViewControl : System.Web.UI.UserControl, IMonthView
{
   //1. User control has no method other than view defined method for attaching presenter
   //2. Properties has only set method

   private MonthPresenter presenter;

   //Provision for gettng the presenter in User Control from aspx page.
   public void AttachPresenter(MonthPresenter presenter)
   {
      if (presenter == null)
      {
         throw new ArgumentNullException("presenter may not be null");
      }
      this.presenter = presenter;
   }

   //Implement View's Property
   public string MonthName
   {
      set
      {
        //During set of the popert, set the control's value
        lblMonth.Text = value.ToString();
      }
   }

   protected void Page_Load(object sender, EventArgs e)
   {

   }    
}

ASPX Page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ShowMeTheTime.aspx.cs"      Inherits="ShowTime" %>

<%@ Register TagPrefix="mvpProject" TagName="CurrentTimeView" Src="Views/CurrentTimeView.ascx" %>

<%@ Register TagPrefix="month" TagName="MonthView" Src="Views/MonthViewControl.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>PAGE TITLE </title>
</head>
<body>
<form id="form1" runat="server">

    <mvpProject:CurrentTimeView id="ucCtrlcurrentTimeView" runat="server" 
    />
    <br />
    <br />
    <month:MonthView id="ucCtrlMonthView" runat="server" />

</form>
</body>
</html>

using System;
using System.Web.UI;

public partial class ShowTime : Page
{
    CurrentTimePresenter currentTimePresenter;
    MonthPresenter monthPresenter;

    protected void Page_Load(object sender, EventArgs e) 
    {
       HelperInitCurrentTimeView();
       HelperInitMonth();
    }

    private void HelperInitMonth()
    {
       //Create presenter
       monthPresenter = new MonthPresenter(ucCtrlMonthView);

       //Pass the presenter object to user control
       ucCtrlMonthView.AttachPresenter(monthPresenter);
    }

    private void HelperInitCurrentTimeView() 
    { 
       //Cretes presenter by passing view(user control) to presenter.
       //User control has implemented IView
       currentTimePresenter = new CurrentTimePresenter(ucCtrlcurrentTimeView);

        //Pass the presenter object to user control
        ucCtrlcurrentTimeView.AttachPresenter(currentTimePresenter);

        //Call the presenter action to load time in user control.
        currentTimePresenter.SetCurrentTime(Page.IsPostBack);

        //Event described in User Control ???? Subsribe for it.
        ucCtrlcurrentTimeView.myBtnAddDaysClickedEvent += new Views_CurrentTimeView.OnAddDaysClickedDelegate(CurrentTimeViewControl_AddButtonClicked_MainPageHandler);        
    }

    void CurrentTimeViewControl_AddButtonClicked_MainPageHandler(string strValue)
    {
       string monthValue = "l";
       monthPresenter.SetMonth("SAMPLE VALUE");
       //myGridCntrl.CurentCharacter = theLetterCtrl.SelectedLetter;
       //myGridCntrl.LoadGridValues();
    }
}

Some MVP discussions:

Model View Presenter - Guidelines

In MVP where to write validations

MVP - Should views be able to call presenter methods directly or should they always raise events?

MVP events or property

The Model in MVP - Events

MVP - Should the Presenter use Session?

Why do Presenters attach to View events instead of View calling Presenter Methods in most ASP.NET MVP implementations?

Public Methods or subscribe to View events

MVP pattern, how many views to a presenter?

MVP and UserControls and invocation

ASP.NET Web Forms - Model View Presenter and user controls
controls

Restrict violation of architecture - asp.net MVP

Control modification in presentation layer

Decoupling the view, presentation and ASP.NET Web Forms
web-forms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弥枳 2025-01-02 10:29:02

代码太长了。

我就是这样做的。
你说同一页面上有2个控件。因此,可以通过具有 TimeVM 和 MonthVM 的引用(成员)的 ContainerVM 来提供服务。

  1. 每当您执行操作时,TimeVM 都会更新后备属性 ResultantDate。
  2. ContainerVM 已订阅 TimeVM.ResultantDate 的属性更改通知。每当它收到更改通知时,它都会调用 MonthVM.SetMonth()

现在可以在不使用任何视图的情况下进行测试 - 纯粹在演示者级别。

TLDR the code.

Here's how I would do it.
You say there are 2 controls on the same page. So that can be served by a ContainerVM with references (members) of TimeVM and MonthVM.

  1. TimeVM updates a backing property ResultantDate whenever you do your thing.
  2. ContainerVM has subscribed to property-changed notifications for TimeVM.ResultantDate. Whenever it receives a change notification, it calls MonthVM.SetMonth()

This can now be tested without using any views - purely at the presenter level.

小耗子 2025-01-02 10:29:02

感谢您的投入。我提到了 MVP 快速入门 http://msdn.microsoft.com/en-us/library /ff650240.aspx模型可以引发事件。我想,我应该采用这种方法。欢迎任何想法。

另外,我发布了 http://forums.asp。 net/t/1760921.aspx/1?Model+View+Presenter+Guidelines 收集 MVP 的一般规则。

引用

开发可以与View和Model通信的Presenter。
演示者可能只了解视图界面。即使
具体视图更改,不会影响演示者。

在具体视图中,控件的事件处理程序将简单地调用
演示者方法或引发演示者将拥有的事件
订阅了。不应有任何表示规则/逻辑写入
具体视图。

Presenter应该只有模型的接口对象;不具体
模型。这是为了便于单元测试

视图可以引用业务实体。但不应该有逻辑
与实体对象相关联的编写。它可能只是通过
实体对象到演示者。

视图界面应该是一个抽象。它不应该有任何
控件或 System.Web 参考。具体来看,不应该有
接口定义方法以外的方法。

“模型”永远不知道具体的视图以及
界面视图

“模型”可以定义和引发事件。演示者可以订阅这些
模型引发的事件。

presenter 中的公共方法应该是无参数的。查看对象
应该只访问演示者的无参数方法。另一种选择
视图可以定义演示者可以订阅的事件。任何一个
方式,不应该有参数传递。

由于模型具有所有必需的值(要存储回
数据库),不需要从视图向模型传递任何值(大多数
的时间)。例如,当在下拉列表中选择一个项目时,仅
控件的当前索引需要传递给模型。然后模型知道
如何获取对应的域值。在这种情况下,视图
不需要向演示者传递任何内容。演示者知道如何获得价值
从视图中。

视图可以直接使用模型(不使用演示者)。例如
ObjectDataSource 的 Select 方法。但控制器永远不知道
具体视图以及界面视图。

演示者引用视图接口而不是视图的
具体实施。这允许您替换实际视图
运行单元测试时使用模拟视图。

Thanks for the inputs. I referred MVP Quickstarts http://msdn.microsoft.com/en-us/library/ff650240.aspx. Model can raise events. I think, I should go with that approach. Any thoughts are welcome.

Also, I have posted http://forums.asp.net/t/1760921.aspx/1?Model+View+Presenter+Guidelines to collect general rules on MVP.

Quote

Develop Presenter which can communicate with both View and Model.
Presenter may only have knowledge of view interfaces. Even if the
concrete view changes, it does not affect presenter.

In the concrete view, control’s event handlers will simply call
presenter methods or raise events to which presenter would have
subscribed. There should be no presentation rule/logic written in
concrete view.

Presenter should have only interface object of model; not concrete
model. This is for the ease of Unit Testing

View can refer business entities. However there should no logic
written associated with the entity objects. It may just pass the
entity object to presenter.

View interface should be an abstraction. It should NOT have any
control or System.Web reference. In concrete view, there should be no
method other than interface defined methods.

The "Model" never knows about the concrete view as well as the
interface view

"Model" can define and raise events. Presenter can subscribe these
events raised by model.

Public methods in presenter should be parameterless. View object
should access only parameterless methods of presenter. Another option
is view can define events to which the presenter can subscribe. Either
way, there should be no parameter passing.

Since the model has all the required values (to be stored back in
database), there is no need to pass any value to model from view (most
of the time). E.g. when an item is selected in dropdown list only the
controls’ current index need to be passed to model. Then model knows
how to get the corresponding domain values. In this case, the view
need not pass anything to presenter. Presenter knows how to get value
from view.

View may make use of model directly (without using presenter). E.g.
ObjectDataSource's SelectMethod. But controller never knows about the
concrete view as well as the interface view.

The presenter references the view interface instead of the view's
concrete implementation. This allows you to replace the actual view
with a mock view when running unit tests.

一曲爱恨情仇 2025-01-02 10:29:02

我对 ASP.net 没有经验,但我想我遵循了你想要做的事情的要点。

看来您要通过为各个 UI 元素制作演示者来提高演示者的水平。在本例中为月份和时间。我更愿意将其视为 ShowTime 时期。 ShowTime 能够显示月份和时间。

与 MVP 一起使用。然后您将需要页面将实现的 IShowTimeView。 (不是控件)。然后编写一个使用 IShowTimeView 发送和检索值的 ShowTimePresenter。

您将使 ShowTime 实现 IShowTimeView 接口。它将时间、AddDay 事件和月份等项目路由到页面上的实际控件或从页面上的实际控件路由这些项目。

所以如果我理解你的文章。事件的顺序大概是这样的。

用户输入要添加的天数。
用户单击添加天数
添加天数会触发调用 Present 上的方法来添加天数的事件。
演示者中添加天数的方法将进行计算和其他所需的步骤。
然后,add days 方法将使用 Presenter 中的视图指针告诉视图使用计算值更新月份。
然后,视图将采用计算值在控件上设置正确的属性。

要进行单元测试,您需要创建一个实现 IShowTimeView 的模拟对象,并使用它来代替实际的页面对象。

I am not experienced with ASP.net but I think I follow the gist of what you are trying to do.

It appears that you are going down to fine a level with your presenter by making presenters for the individual UI elements. In this case the Month and the Time. I would think of it more as ShowTime period. ShowTime has the capability of showing the Month and Time.

To use this with MVP. Then you will need a IShowTimeView that the page will implement. (Not the controls). And then write a ShowTimePresenter that uses IShowTimeView to send and retrieve values.

You will have ShowTime implement the IShowTimeView interface. It will route items like the Time, AddDay events, and the Month to and from the actual controls on the page.

So if I understand your writeup. The sequence of event would be something like this.

The user types in the days to add.
The user clicks add days
Add Days fires the event which calls a method on the Present to add days.
The method in the presenter that add days will make it's calculation and other needed steps.
The add days method will then use the View pointer in the Presenter to tell the view to update the Month with the calculated value.
The View will then take the calculated value set the correct property on the control.

To do unit testing you need to make a mock object implementing IShowTimeView and use that in place of the actual page object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文