21.4.9 为订单选择产品
当显示选择产品的视图时,希望显示订单ID和客户名称的控件所对应的变量已经被设置为适当的数值。我们打算使用文档对象的Order成员获得这些值。为此,可以给CProductView类添加一个函数。可以将其命名为InitializeView(),该函数的返回类型为void。可以从应用程序的CMainFrame对象拥有的SelectView()成员中调用该函数。这样可以确保这两个控件总是在显示产品选择对话框之前被初始化。
在实现InitializeView()函数之前,需要考虑另外一件事情。新的Orders表记录仅当为了初次给该订单添加产品而单击Select Product按钮时才应该添加。以后的按钮单击只应该给该订单添加另一种产品,因此需要某种方法来确定单击Select Product按钮时Orders表是否已经添加过新订单。要做到这一点,可以给CProductView类添加一个bool类型的变量m_OrderAdded。该变量最初为false,由Select Product按钮的处理程序将其设置为true。因此,给CProductView类添加该变量。可以在InitializeView()成员中初始化m_OrderAdded变量,InitializeView()函数的实现如下所示:
- void CProductView::InitializeView()
- {
- // Get a pointer to the document
- CDBSimpleUpdateDoc* pDoc =
- static_cast<CDBSimpleUpdateDoc*>(GetDocument());
- m_OrderID = pDoc->m_Order.m_OrderID;
- m_CustomerName = pDoc->m_Order.m_ShipName;
- m_Quantity = 1; // Must order at least 1
- m_Discount = 0; // No default discount
- m_OrderAdded = false; // Order not added initially
- UpdateData(FALSE); // Transfer data to controls
- }
该函数通过复制文档对象中Order成员的适当成员的数值,初始化视图类中对应订单ID和客户名称控件的成员。该函数还可以确保订购数量和折扣控件最初拥有适当的初值。任何产品的订购数量都必须至少是1,而折扣值默认是0。正如先前所看到的那样,以实参值FALSE调用继承的UpdateData()成员,使数据从类变量传输到控件上。需要在该源文件的开始处添加嵌入DBSimpleUpdateDoc.h头文件的#include指令,从而使Document类定义可用。
为了使该函数投入使用,只需在切换到产品选择对话框时调用InitializeView()即可。做这件事的位置显然是在CMainFrame类的SelectView()成员中:
- void CMainFrame::SelectView(ViewID viewID)
- {
- CView* pOldActiveView = GetActiveView();
// Get current view -
- // Get pointer to new view if it exists
- // if it doesn't the pointer will be null
- CView* pNewActiveView = static_cast<CView*>(GetDlgItem(viewID));
-
- // If this is first time around for the new view, the new view
- // won't exist, so we must create it
- // The Order Details view is always created first so we don't need
- // to provide for creating that.
- if (pNewActiveView == NULL)
- {
- switch(viewID)
- {
- case NEW_ORDER: // Create view to add new order
- pNewActiveView = new CCustomerView;
- break;
- case SELECT_PRODUCT: // Create view to add product to order
- pNewActiveView = new CProductView;
- break;
- default:
- AfxMessageBox(_T("Invalid View ID"));
- return;
- }
-
- // Switching the views
- // Obtain the current view context to apply to the new view
- CCreateContext context;
- context.m_pCurrentDoc = pOldActiveView->GetDocument();
- pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault,
- this, viewID, &context);
- pNewActiveView->OnInitialUpdate();
- }
- SetActiveView(pNewActiveView); // Activate the new view
- if(viewID==NEW_ORDER)
- static_cast<CCustomerView*>(pNewActiveView)->SetNewOrderID();
- else if(viewID == SELECT_PRODUCT)
- static_cast<CProductView*>(pNewActiveView)->InitializeView();
-
- pOldActiveView->ShowWindow(SW_HIDE); // Hide the old view
- pNewActiveView->ShowWindow(SW_SHOW); // Show the new view
- pOldActiveView->SetDlgCtrlID(m_CurrentViewID);
// Set the old view ID - pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
- m_CurrentViewID = viewID; // Save the new view ID
- RecalcLayout();
- }
当形参viewID的值是SELECT_PRODUCT时,CProductView类中对应订单ID和客户名称控件的变量将被初始化,同时被初始化的还有控制着是否在Orders表中创建新记录的bool变量。