MFC中的DoDataExchange(CDataExchange* pDX)是用来绑定控件与成员变量的。
DoDataExchange为虚函数——virtual void DoDataExchange(CDataExchange* pDX);
void CMyView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, m_comboxTest);
}
其中IDC_COMBO01为CComboBox对象的ID,m_comboxTest为与之关联的对象,通过DDX_Control(pDX, IDC_COMBO1, m_comboxTest);将控件与变量绑定。绑定后通过调用UpdateData(TRUE)将控件里的值写入变量,UpdateData(FLASE)将变量的值写入控件。
看起来So easy,不过如果如果不注意其他细节,绑定将失败。
什么细节呢?
如果新创建一个CForm的窗口资源,并通过向导添加一个自定义的FormView窗口类,如class CMyView : public CFormView{};向导自动生成代码时虚函数只有一个
virtual void DoDataExchange(CDataExchange* pDX),然后通过绑定技术绑定控件与变量以为大功告成,其实不然。按照这个方法来做,被绑定的变量是不能完成初始化的,如果直接使用这个未初始化的变量程序十有八九会崩掉。
那问题出在哪了?如果在DoDataExchange设个断点进行调试,发现重载的DoDataExchange方法根本没有被调用,不被调用当然就不能初始化那个变量了。
怎样解决呢?那就是重载另一个虚函数——virtual void OnInitialUpdate();
实现如下:
void CMyView::OnInitialUpdate()
{
CFormView::OnInitialUpdate(); //关键所在
//other codes
}
CFormView::OnInitialUpdate();这一句不能少,是关键所在。
基类的OnInitialUpdate函数调用了CWnd的UpdateData(FLASE),而正是UpdateData才会调用我们的DoDataExchange函数,至此被绑定的变量才得以初始化。
所以自定义的窗口类如果要绑定控件与变量,一定要重载虚函数virtual void OnInitialUpdate(),并在里面调用基类的OnInitialUpdate方法。