Purpose
Estimated time to complete this lab: 30 minutes
In the View-Presenter pattern, the presenter contains the logic to respond to user events (such as updating or retrieving data) and manipulates the state of the view. The Web Client Software Factory contains the data source control ObjectContainerDataSource. This control implements data binding in a way that easily integrates with the View-Presenter pattern.
You can think of the ObjectContainerDataSource control as a container of objects. You programmatically populate the container, and the container raises events when changes occur to any of the contained objects. This design allows the view (Web page) to delegate the responsibility of performing select operations, update operations, delete operations, and insert operations to the presenter. Figure 1 illustrates the request process for a view that uses the ObjectContainerDataSource control in an implementation of the View-Presenter pattern.
Figure 1
Sample implementation of the View-Presenter pattern
In this exercise, you will create a new view for creating transfers. The view will contain a DetailsView control, which allows users to create new transfers, and a GridView control, which shows the existing transfers, as shown in Figure 2.
Figure 2
New Transfer view
This view will contain an ObjectContainerDataSource control; both the GridView control and the DetailsView control use it as the data source. In this exercise, you will also implement the logic to retrieve and update the data in the presenter and in the module controller.
Preparation
Before proceeding with this lab, you must install and configure the prerequisite software. For more information, see Web Client Software Factory Hands-On Labs.
Open the solution for the previous lab (either the one that you created or the end solution for that lab.) If you use the provided end solution, you must enable the guidance package for that solution.
To enable the Web Client Development guidance package with the Guidance Package Manager
1. Using Visual Studio, open the solution.
2. On the Tools menu, click Guidance Package Manager.
3. In the Guidance Package Manager dialog box, click Enable / Disable Packages.
4. In the Enable and Disable Packages dialog box, select the Web Client Development check box.
5. Click OK.
Procedures
This lab includes the following tasks:
· Task 1: Create the NewTransferView View in the EFT Module
· Task 2: Add the ObjectContainerDataSource Control to the View
· Task 3: Add a DetailsView That Binds to the ObjectContainerDataSource
· Task 4: Add a GridView Control That Binds to the ObjectContainerDataSource
· Task 5: Update the View Interface
· Task 6: Implement the View Logic
· Task 7: (Optional) Unit Test the Presenter
· Task 8: Implement the Presenter
· Task 9: Update the Controller
· Task 10: Provide Navigation to the NewTransferView View
The next sections describe each of these tasks.
Task 1: Create the NewTransferView View in the EFT Module
In this task, you will add a view named NewTransferView to the EFT module using the Add View (with presenter) recipe.
To create the NewTransferView view
· In the Web site’s EFT folder, create a new view named NewTransferView. To do this, right-click the EFT folder inside the DevelopmentWebsite, point to Web Client Factory, and then click Add View (with Presenter) (C#). In the View name box of the recipe wizard, type NewTransferView, and then click Finish.
Task 2: Add the ObjectContainerDataSource Control to the View
In this task, you will add the ObjectContainerDataSource control to the view. Both the GridView control and the DetailsView control that you will add in subsequent tasks will use it as their data source.
To add the ObjectContainerDataSource control to the view
1. In Design view, open the Web page. Drag an ObjectContainerDataSource control from the Toolbox onto the Web page.
Note: To add the ObjectContainerDataSource control in the Toolbox, right-click the Data tab in the Toolbox, and then click Choose Items. On the .NET Framework Components tab, click Browse, select the Microsoft.Practices.Web.UI.WebControls.dll assembly (located in %WCSF_INSTALL_DIR%/Microsoft Practices Library/Microsoft.Practices.Web.UI.WebControls.dll), and then click Open. In the list of components, click ObjectContainerDataSource, and then click OK. Figure 3 illustrates the NewTransfersView page as it appears in Design view with the ObjectContainerDataSource control.
Figure 3
ObjectContainerDataSource control in Design view
After you add the ObjectContainerDataSource control to the Web page, you must to configure it. The key property you need to configure is the DataObjectTypeName property. This property specifies the type of objects that the ObjectContainerDataSource control will contain. Consider the following requirements for the object type:
· If you want to perform update operations, delete operations, or insert operations, the type you select must have a constructor with no parameters.
· If you want to perform update operations or delete operations, the type must have a property that uniquely identifies each instance of that type. This property is the key for the collection of items in the ObjectContainerDataSource control. The control supports composite keys. This means you can use more than one property to form a key for a particular object type.
To set the DataObjectTypeName property, you can manually set it using the Properties window or you can use the Configure Data Source wizard. In the next steps, you will use the Configure Data Source wizard to configure the ObjectContainerDataSource control to use objects of type Transfer.
2. If the ObjectContainerDataSource Tasks shortcut menu does not appear, right-click the ObjectContainerDataSource control, point to Show Smart Tag, and then click Configure Data Source.
3. In the Configure Data Source dialog box, select the data object type GlobalBank.EFT.BusinessEntities.Transfer.
Note: If you do not see the type GlobalBank.EFT.BusinessEntities.Transfer, build the DevelopmentWebsite site, and then return to the Configure Data Source dialog box.
4. Click OK. The dialog box sets the DataObjectTypeName property of the ObjectContainerDataSource control to the name of the selected type.
5. In the Properties window for the control, set the ID property to TransfersDataSource.
6. To see the markup corresponding to the TransfersDataSource control, open the Source view. You should see the following markup.
<asp:Content ID="content" ContentPlaceHolderID="DefaultContent" Runat="Server">
<h1>NewTransferView</h1>
<pp:ObjectContainerDataSource ID="TransfersDataSource" runat="server" DataObjectTypeName="GlobalBank.EFT.BusinessEntities.Transfer" />
</asp:Content>
Task 3: Add a DetailsView That Binds to the ObjectContainerDataSource
In this task, you will add a DetailsView control to the Web page. This control will let users create a new transfer that will be bound to the TransfersDataSource control.
To add a DetailsView that binds to the ObjectContainerDataSource
1. In the Design view, drag a DetailsView control from the Toolbox onto the Web page.
2. In the Choose Data Source drop-down menu on the Smart Tag, select TransfersDataSource to bind the DetailsView control to the TransfersDataSource control. (If the DetailsView Tasks shortcut menu does not appear, right-click the DetailsView control, and then click Show Smart Tag.)
3. Click Edit Fields.
4. Under Selected fields in the Fields dialog box, delete the Status field and the Id field.
5. Under Selected fields, change the order of the fields to the following:
a. SourceAccount
b. TargetAccount
c. Amount
6. Change the HeaderText property of the SourceAccount field to “From Account:”
7. Change the HeaderText property of the TargetAccount field to “To Account:”
8. Change the HeaderText property of the Amount field to “Amount:”. The Fields dialog box should look like the one illustrated in Figure 4.
Figure 4
Configuration of the fields for the DetailsView control
9. Under Available fields, expand the CommandField node, select New, Insert, Cancel, and then click Add.
10. Under Selected fields, select the New, Insert, Cancel field, and then click Add.
11. Under CommandField properties, do the following:
a. Set the ButtonType property to Button.
b. Enter Add as the value for the InsertText property.
c. Set the ShowCancelButton property to False.
d. Set the ShowInsertButton property to True.
12. Click OK to close the Fields dialog box.
13. Set the DefaultMode property of the DetailsView control to Insert.
14. Set the Gridlines property for the DetailsView control to None.
15. Increase the width of the DetailsView control. Using your mouse, drag the right-side border of the DetailsView control to the right until the Width property is approximately 320px.
16. Switch to the Source view for the page and verify the markup matches the following.
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataSourceID="TransfersDataSource"
DefaultMode="Insert" GridLines="None" Height="50px" Width="320px">
<Fields>
<asp:BoundField DataField="SourceAccount" HeaderText="From Account:" SortExpression="SourceAccount" />
<asp:BoundField DataField="TargetAccount" HeaderText="To Account:" SortExpression="TargetAccount" />
<asp:BoundField DataField="Amount" HeaderText="Amount:" SortExpression="Amount" />
<asp:CommandField ButtonType="Button" InsertText="Add" ShowCancelButton="False" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
Task 4: Add a GridView Control That Binds to the ObjectContainerDataSource
In this task, you will add a GridView control to the Web page that will display the created transfers. The GridView control will be bound to the TransfersDataSource control.
To add a GridView control that binds to the ObjectContainerDataSource
1. Open the Source view for the Web page, and then add the following HTML after the DetailsView control to add a horizontal line and a header.
<hr/>
<h3>Current Transfers</h3>
2. Add a GridView control below the header you added in the previous step, and then bind the GridView to the TransfersDataSource object. To do this, switch to the Design view, and then drag a GridView control from the Toolbox below the Current Transfer header. In the Choose Data Source drop-down menu on the Smart Tag, click TransfersDataSource to bind the GridView control to the TransfersDataSource control. (If the GridView Tasks shortcut menu does not appear, right-click the GridView control, and then click Show Smart Tag.
3. Under Available fields, expand the CommandField node, select Edit, Update, Cancel, and then click Add.
4. Under Selected fields, change the order of the fields to the following:
a. CommandField
b. Amount
c. SourceAccount
d. TargetAccount
5. Under Selected fields, select the Edit, Update, Cancel field, and then click Add.
6. Under CommandField properties, do the following:
a. Set the ShowCancelButton property to False.
b. Set the ShowDeleteButton property to True.
c. Set the ShowEditButton property to False.
7. Click OK to close the Fields dialog box.
The data source control uses the data object type's key properties to uniquely identify an object. To enable update operations and delete operations, you must specify the names of the key properties of your data object in the data-bound control that consumes the data source control. In the next step, you will specify in the GridView control that the Id property of a Transfer object is the identifier.
8. Set the DataKeyNames property of the GridView control to Id.
Note: If you do not see the expected columns in the GridView control after you set the DataKeyNames property, right-click the Web page, and then click Refresh.
9. Remove the Status and Id field as a bound column. To do this, click Edit Columns in the GridView Tasks shortcut menu. Under Selected fields, remove the Status and Id fields.
10. Set the AutoGenerateDeleteButton and AutoGenerateEditButton properties to True to have the GridView control automatically create buttons for edit and delete operations.
At run time, data-bound controls, such as the GridView control on the Web page, can display the objects contained in the ObjectContainerDataSource control. To display the objects, you must add them to the ObjectContainerDataSource control. To add them, you set the DataSource property of the control to an object or to a list of objects when the view loads. You will do this in a subsequent task to populate the TransfersDataSource control with Transfer objects.
Note: When working with the ObjectContainerDataSource control, you can set the DataSource property to one of the following objects:
· A single data object of the type you set in the configuration wizard
· An object that implements the IEnumerable interface whose items are of the type you set in the DataObjectTypeName property
If you attempt to add objects that do not match the type defined in the Configure Data Source dialog box, the ObjectContainerDataSource control will throw an exception of type InvalidOperationException.
Task 5: Update the View Interface
In this task, you will update the view’s interface to include a write-only property named Transfers. The presenter will use this property to set the transfers that the view should display when the view loads.
To update the view interface
1. Open the file INewTransferView.cs and add the following using statement.
using GlobalBank.EFT.BusinessEntities;
2. Use the following code to define the interface.
public interface INewTransferView
{
IList<Transfer> Transfers { set; }
}
Task 6: Implement the View Logic
In this task, you will implement the view logic. The view is responsible for forwarding user events to the presenter and for displaying the transfers.
To implement the view logic
1. Add the following using statements to the NewTransfersView.aspx.cs file located in the EFT folder of the Web site.
using System.Collections.Generic;
using GlobalBank.EFT.BusinessEntities;
2. Implement the Transfers property to set the DataSource property of the TransfersDataSource control, as shown in the following code. The presenter will use this property to populate the control.
#region INewTransfersView Members
public IList<Transfer> Transfers
{
set { TransfersDataSource.DataSource = value; }
}
#endregion
When the user performs an update operation, insert operation, or delete operation in a data-bound control, the ObjectContainerDataSource control raises the following events, respectively.
public event EventHandler<ObjectContainerDataSourceStatusEventArgs> Updated;
public event EventHandler<ObjectContainerDataSourceStatusEventArgs> Inserted;
public event EventHandler<ObjectContainerDataSourceStatusEventArgs> Deleted;
To reflect the changes made by the user in the underlying data store of your application, you must handle these events in the view and perform the required actions to update the data store. When using the View-Presenter pattern, you typically call methods in the presenter to handle the operations. In the next steps, you will write code to handle the Inserted event, which is raised when a user submits a transfer in the DetailsView control that you added to the Web page.
3. Switch to the Design view, and then click the TransfersDataSource control. In the Properties window, open the events list, and then double-click the Inserted event to create an event handler.
4. In the event handler body, forward the event to the presenter, as shown in the following highlighted code.
protected void TransfersDataSource_Inserted(object sender, Microsoft.Practices.Web.UI.WebControls.ObjectContainerDataSourceStatusEventArgs e)
{
_presenter.OnTransferAdded((Transfer)e.Instance);
}
5. Repeat steps 3 and 4 for the Updated event and Deleted event. Use the following code for the event handlers.
protected void TransfersDataSource_Deleted(object sender, Microsoft.Practices.Web.UI.WebControls.ObjectContainerDataSourceStatusEventArgs e)
{
_presenter.OnTransferDeleted((Transfer)e.Instance);
}
protected void TransfersDataSource_Updated(object sender, Microsoft.Practices.Web.UI.WebControls.ObjectContainerDataSourceStatusEventArgs e)
{
_presenter.OnTransferUpdated((Transfer)e.Instance);
}
If you build the solution now, there will be compilation errors because the presenter does not contain the OnTransferAdded, OnTransferDeleted, and OnTransferUpdated methods, and the MockNewTransferView view does not fully implement the INewTransferView interface (the MockNewTransferView class was automatically created by the Add View (with presenter) recipe). In the next steps, you will add the missing methods to the presenter and the mock view so that you can build your solution.
6. Open the file EFT/Views/NewTransferViewPresenter.cs and add the following using statement.
using GlobalBank.EFT.BusinessEntities;
7. Add the following code to the EFT/Views/NewTransferViewPresenter.cs file.
public void OnTransferAdded(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
public void OnTransferUpdated(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
public void OnTransferDeleted(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
8. Open the file the NewTransferViewPresenterFixture.cs. This file is located in the Views folder of the EFT.Tests project.
9. Add the following using statement.
using GlobalBank.EFT.BusinessEntities;
10. In the MockNewTransferView class body, implement the Transfers property, as shown in the following code.
public IList<GlobalBank.EFT.BusinessEntities.Transfer> Transfers
{
set { throw new Exception("The method or operation is not implemented."); }
}
11. Build the solution.
Task 7: (Optional) Unit Test the Presenter
In this task, you will write unit tests for the NewTransferViewPresenter class before implementing its logic. If you are not interested in writing unit tests for this class, you can skip this task and move to the next one.
To unit test the presenter
1. Open the NewTransferViewPresenterFixture.cs file. This file is located in the Views folder of the EFT.Tests project.
2. Add the following using statements.
using GlobalBank.EFT.Tests.Mocks;
3. Replace the MockNewTransferView definition with the following code.
class MockNewTransferView : INewTransferView
{
private IList<Transfer> _transfers = null;
#region ITransfersView Members
public IList<Transfer> Transfers
{
set { _transfers = value; }
get { return _transfers; }
}
#endregion
}
4. The presenter will call methods in the controller to perform insert, update, delete, and select operations for the transfers. Declare them in the controller so that you can override them in the mock EFTController class. To do this, open the EFTController.cs file located in the root of the EFT project, and then add the following code.
public virtual void AddTransfer(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
public virtual void DeleteTransfer(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
public virtual void UpdateTransfer(Transfer transfer)
{
throw new Exception("The method or operation is not implemented.");
}
public virtual ReadOnlyCollection<Transfer> GetTransfers()
{
throw new Exception("The method or operation is not implemented.");
}
5. Add the following using statements.
using GlobalBank.EFT.BusinessEntities;
using System.Collections.ObjectModel;
6. Open the Mocks/MockEFTController.cs file and add the following using statement.
using GlobalBank.EFT.BusinessEntities;
using System.Collections.ObjectModel;
7. Add the following fields to the MockEFTController class.
public List<Transfer> MockTransfers = new List<Transfer>();
public bool AddTransferCalled = false;
public bool UpdateTransferCalled = false;
public Transfer UpdatedTransfer = null;
public bool DeleteTransferCalled = false;
public Transfer DeletedTransfer = null;
8. Override the AddTransfer, UpdateTransfer, DeleteTransfer and GetTransfers methods, as shown in the following code.
public override void AddTransfer(Transfer transfer)
{
AddTransferCalled = true;
MockTransfers.Add(transfer);
}
public override void UpdateTransfer(Transfer transfer)
{
UpdateTransferCalled = true;
UpdatedTransfer = transfer;
}
public override void DeleteTransfer(Transfer transfer)
{
DeleteTransferCalled = true;
DeletedTransfer = transfer;
}
public override ReadOnlyCollection<Transfer> GetTransfers()
{
return MockTransfers.AsReadOnly();
}
The presenter is responsible for setting the transfers in the view when the view loads, and for handling insert, delete, and update transfers operations. In the next step, you will create unit tests to verify this behavior.
9. Go back to the NewTransferViewPresenterFixture.cs file and add the following unit tests.
[TestMethod]
public void OnViewLoadedSetsTransfersInTheView()
{
MockEFTController controller = new MockEFTController();
Transfer transfer = new Transfer();
controller.MockTransfers.Add(transfer);
NewTransferViewPresenter presenter = new NewTransferViewPresenter(controller);
MockNewTransferView view = new MockNewTransferView();
presenter.View = view;
presenter.OnViewLoaded();
Assert.AreEqual(1, view.Transfers.Count);
Assert.AreSame(transfer, view.Transfers[0]);
}
[TestMethod]
public void OnTransferAddedCallsControllerAddTransfer()
{
MockEFTController controller = new MockEFTController();
Transfer transfer = new Transfer();
NewTransferViewPresenter presenter = new NewTransferViewPresenter(controller);
presenter.OnTransferAdded(transfer);
Assert.IsTrue(controller.AddTransferCalled);
Assert.AreSame(transfer, controller.MockTransfers[0]);
}
[TestMethod]
public void OnTransferUpdatedCallsControllerUpdateTransfer()
{
MockEFTController controller = new MockEFTController();
Transfer transfer = new Transfer();
NewTransferViewPresenter presenter = new NewTransferViewPresenter(controller);
presenter.OnTransferUpdated(transfer);
Assert.IsTrue(controller.UpdateTransferCalled);
Assert.AreSame(transfer, controller.UpdatedTransfer);
}
[TestMethod]
public void OnTransferDeletedCallsControllerDeleteTransfer()
{
MockEFTController controller = new MockEFTController();
Transfer transfer = new Transfer();
NewTransferViewPresenter presenter = new NewTransferViewPresenter(controller);
presenter.OnTransferDeleted(transfer);
Assert.IsTrue(controller.DeleteTransferCalled);
Assert.AreSame(transfer, controller.DeletedTransfer);
}
If you attempt to run the tests now, there will be compilation errors. This happens because the presenter does not have a constructor that receives an EFTController instance as a parameter.
10. Uncomment the constructor generated by the Add View (with presenter) recipe.
private EFTController _controller;
public NewTransferViewPresenter([CreateNew] EFTController controller)
{
_controller = controller;
}
11. Use the Test Manager to run the tests. You should see that the tests you created in the previous task fail. They fail because you have not yet implemented the presenter logic.
Note: If you are not familiar with the Test Manager, use the following steps to run the tests:
a. In Solution Explorer, click EFT.Tests.
b. On the Test menu, click Start Selected Tests Project without Debugger (or press CTRL+SHIFT+X).
The results will display in the Test Results window.
Task 8: Implement the Presenter
In this task, you will implement the presenter logic. The presenter is responsible for setting the transfers in the view when the view loads and for handling the insert, update, and delete transfers operations.
To implement the presenter
1. Open the file EFT/Views/NewTransferViewPresenter.cs. If you performed Task 7, skip the next step and continue with step 3.
2. Implement the constructor to have ObjectBuilder inject an EFTController instance as a parameter. To do this, uncomment the constructor generated by the Add View (with presenter) recipe.
private EFTController _controller;
public NewTransferViewPresenter([CreateNew] EFTController controller)
{
_controller = controller;
}
3. When the view loads, set its Transfers property to the list of current transfers. To do this, replace the OnViewLoaded method body with the following code. In the next task, you will implement the GetTransfers method in the controller.
public override void OnViewLoaded()
{
this.View.Transfers = _controller.GetTransfers();
}
4. Implement the OnTransfersAdded method. In this method, call a method in the controller to add the transfer, as shown in the following code. In the next task, you will implement the method in the controller.
public void OnTransferAdded(Transfer transfer)
{
_controller.AddTransfer(transfer);
}
5. Implement the OnTransfersUpdated method, as shown in the following code.
public void OnTransferUpdated(Transfer transfer)
{
_controller.UpdateTransfer(transfer);
}
6. Implement the OnTransfersDeleted method, as shown in the following code.
public void OnTransferDeleted(Transfer transfer)
{
_controller.DeleteTransfer(transfer);
}
7. If you created unit tests for the presenter, run them. They should pass.
Task 9: Update the Controller
In this task, you will implement the GetTransfers and the AddTransfer methods in the controller. To implement these methods, you will store the transfers created by the user in the ASP.NET session.
To update the controller
1. In the EFT project, add a reference to the System.Web assembly. (You must do this because you will store the transfers the user creates in the ASP.NET session.) To do this, right-click the EFT project node in Solution Explorer, and then click Add Reference. On the .NET tab, select System.Web, and then click OK.
2. Open the file EFTController.cs located in the root of the EFT project.
3. Add the following using statements (if you did not previously add them.)
using GlobalBank.EFT.BusinessEntities;
using System.Collections.ObjectModel;
using System.Web;
4. Add a private property named Transfers that encapsulates the access to the list of transfers stored in the ASP.NET session, as shown in the following code.
private List<Transfer> Transfers
{
get
{
List<Transfer> transfers = HttpContext.Current.Session["Transfers"] as List<Transfer>;
if (transfers == null)
{
transfers = new List<Transfer>();
Transfers = transfers;
}
return transfers;
}
set
{
HttpContext.Current.Session["Transfers"] = value;
}
}
Note: Typically, the unit tests you write for your Web application do not execute in a Web server. This means there is no session state available when the unit tests execute. When you require your application to store information in the session state, you can use the Composite Web Application Block class StateValue to store the information. This class supports code that runs both in a Web server environment (the session is available, and data is stored there) and outside of a Web server environment (no session is available, such as when you run your unit tests, and the data is stored in memory). For information about how to use the StateValue class to manage state across requests, see ”How to: Use Session State with Unit Testing” in the Web Client Software Factory documentation.
5. Implement the AddTransfer method. In this method, set a new GUID for the transfer received as a parameter and add it to the transfers list. To do this, use the following code.
public virtual void AddTransfer(Transfer transfer)
{
transfer.Id = Guid.NewGuid();
Transfers.Add(transfer);
}
6. Implement the UpdateTransfer and DeleteTransfer methods. In these methods, update the transfer list as required. You can add the following code to define the methods.
public virtual void DeleteTransfer(Transfer transfer)
{
Transfer found = FindTransfer(Transfers, transfer);
if (found != null)
{
Transfers.Remove(found);
}
}
public virtual void UpdateTransfer(Transfer transfer)
{
Transfer found = FindTransfer(Transfers, transfer);
if (found != null)
{
found.SourceAccount = transfer.SourceAccount;
found.TargetAccount = transfer.TargetAccount;
found.Status = transfer.Status;
found.Amount = transfer.Amount;
}
}
private static Transfer FindTransfer(List<Transfer> transfers, Transfer transfer)
{
return transfers.Find(delegate(Transfer match)
{
return transfer.Id == match.Id;
});
}
7. Implement the GetTransfers method. This method should return a read-only collection of Transfer objects. To do this, add the following code.
public virtual ReadOnlyCollection<Transfer> GetTransfers()
{
return Transfers.AsReadOnly();
}
Task 10: Provide Navigation to the NewTransferView View
In this task, you will add a button in the LastTransferView view. Users can click this button to navigate to the NewTransferView view.
To provide navigation to the NewTransferView view
1. Open the Design view for the LastTransferView.aspx page, and then drag a Button control below the NoTransfersPanel.
2. Set the ID property of the button to NewTransferButton.
3. Set the Text property of the button to New Transfer.
4. Double-click the button to have Visual Studio generate an event handler for the click event.
5. In the click event handler, add the bold line from the following code to forward the click event to the presenter.
protected void NewTransferButton_Click(object sender, EventArgs e)
{
_presenter.OnNewTransfer();
}
6. In the presenter, call a method in the controller to start the “create new transfers” process. To do this, open the LastTransferViewPresenter.cs file located in the Views folder of the EFT project, and then add the following code.
public void OnNewTransfer()
{
_controller.CreateNewTransfers();
}
7. In the EFTController class, implement the CreateNewTransfers method. In this method, perform a redirect to the NewTransferView.aspx page. To do this, open the file EFTController.cs, and then add the following code.
public virtual void CreateNewTransfers()
{
System.Web.HttpContext.Current.Response.Redirect("NewTransferView.aspx", true);
}
Note: Typically, the unit tests you write for your Web application do not execute in a Web server. This means there is no HttpContext object available when the unit tests execute. Therefore, if you want to write unit tests for the EFTController class, you need to implement pages navigation in a different way. For example, you could use a navigation service, as explained in “Lab 5: Creating a Foundational Module.”
Verification
In this section, you will verify that the NewTransferView view works as expected.
To verify the NewTransferView view works correctly
1. Build and run the application.
2. Click the Transfers site map node, and then click the New Transfer button.
3. Enter transfers in the DetailsView, and then submit them. The transfers should be listed in the GridView control, as shown in Figure 5.
Figure 5
NewTransferView view
Paging and Sorting with the ObjectContainerDataSource Control
The ObjectContainerDataSource control supports two ways of sorting and paging the items it contains, which are not covered in this lab:
· Default paging and sorting. The control performs paging and sorting. With this approach, the control typically contains the entire collection of items.
· Custom (server-side) paging and sorting. The developer must write code to page and sort the items. With this approach, the control typically contains a subset of items.
For information about how to use the paging and sorting features of the ObjectContainerDataSource control, see ”Paging and Sorting” in Web Client Software Factory Help.