MFC ActiveX 控件:在 ActiveX 控件中使用数据绑定
使用 ActiveX 控件的更强大的功用之一是数据绑定,其允许控件属性与数据库中的特定字段绑定。 当用户修改此绑定属性的数据时,控件通知数据库和更新请求的记录字段。 之后数据库是成功还是失败的通知了请求控件。
本文包含任务的控件一侧。 实现与数据库交互的数据绑定是控件容器的责任。 您如何在容器中管理数据库交互超出了本文档的范围。 您如何准备数据绑定控件在本文的其余部分解释。
数据绑定控件的概念图
COleControl 类提供两个成员函数简化了数据绑定的实现过程。 第一个函数,BoundPropertyRequestEdit,用于请求权限更改属性值。 在属性值成功更改后,第二个函数,BoundPropertyChanged 被调用。
本文涵盖以下主题:
创建一个 Bindable Stock (备用)属性
创建 Bindable 的 get/set 方法
创建一个 Bindable Stock (备用)属性
创建数据绑定的常用属性是可以的,尽管更可能的是您将想要选择 bindable get/set 方法。
备注
默认情况下,常用属性具有 bindable 和 requestedit 特性。
使用"添加属性向导",添加绑定属性
使用 MFC ActiveX 控件向导 开始项目。
右击控件的接口节点。
此操作打开快捷菜单。
从快捷菜单中,单击**“添加”,然后单击“添加属性”**。
从 属性 名称 下拉列表项选择一个实体。 例如,可以选择 文本。
由于 文本 是常用属性,bindable 和 requestedit 特性都已被检查了。
从 IDL 特性 选项卡上中选择下列复选框: displaybind 和 defaultbind 以便在项目的 .IDL 文件中为属性定义添加这些特性。 这些特性使控件向用户可见并使常用属性默认为绑定的属性。
此时,控件可以显示来自数据源的数据,但是,用户不能更新数据字段。 如果希望控件也可以更新数据,请更改 OnOcmCommand OnOcmCommand 函数如下所示:
#ifdef _WIN32
WORD wNotifyCode = HIWORD(wParam);
#else
WORD wNotifyCode = HIWORD(lParam);
#endif
if(wNotifyCode==EN_CHANGE)
{
if(!BoundPropertyRequestEdit(DISPID_TEXT))
{
SetNotSupported();
}
else
{
GetText();
// Notify container of change
BoundPropertyChanged(DISPID_TEXT);
}
}
return 0;
现在可以生成项目,将注册控件。 在在对话框中插入控件,Data Field 和 Data Source (数据源) 属性已添加,并且您可以选择一个数据源和字段在控件中显示。
创建 Bindable 的 get/set 方法
除了数据绑定的 get/set 方法之外,您也可以创建 常用属性绑定
备注
此过程假定您拥有一个 Windows 控件的子类 ActiveX 控件的项目。
使用"添加属性向导",添加绑定的 get/set 方法
加载控件项目。
在 控件设置 页中,选择将控件子类化的的窗口类。 例如,您可能想要子类化编辑控件。
加载控件项目。
右击控件的接口节点。
此操作打开快捷菜单。
从快捷菜单中,单击**“添加”,然后单击“添加属性”**。
在**“属性名称”**框中键入属性的名称。 对于此示例,使用 MyProp。
从**“属性类型”**下拉列表中选择数据类型。 对于此示例,使用 short。
对于 Implementation Type,单击 Get/Set Methods。
从 IDL 特性选项卡上中选择下列复选框: bindable, requestedit,displaybind, 和 defaultbind以便在项目的 .IDL 文件中为属性定义添加这些特性。 这些特性使控件向用户可见并使常用属性默认为绑定的属性。
单击**“完成”**。
修改 SetMyProp 函数的主体,以便包含以下代码:
if(!BoundPropertyRequestEdit(1)) { SetNotSupported(); return; } else { if(AmbientUserMode()) // SendMessage only at run-time { _stprintf_s(m_strText.GetBuffer(10), 10, _T("%d"), newVal); SetWindowText(m_strText); m_strText.ReleaseBuffer(); } else { InvalidateControl(); } // Signal a property change // This is the MFC equivalent of OnChanged() BoundPropertyChanged(1); SetModifiedFlag(); }
传递给 BoundPropertyChanged 和 BoundPropertyRequestEdit 函数的参数作为属性的调度标识符,其也是在 .idl 文件中传递给属性的 ID () 特性的参数。
修改 OnOcmCommand 函数,使其包含以下代码:
#ifdef _WIN32 WORD wNotifyCode = HIWORD(wParam); #else WORD wNotifyCode = HIWORD(lParam); #endif if(wNotifyCode==EN_CHANGE) { if(!BoundPropertyRequestEdit(DISPID_TEXT)) { SetNotSupported(); } else { GetText(); // Notify container of change BoundPropertyChanged(DISPID_TEXT); } } return 0;
修改 OnDraw 函数,使其包含以下代码:
if(!AmbientUserMode()) { // Draw the Text property at design-time pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->DrawText(m_strText, -1, (LPRECT)&rcBounds, DT_LEFT | DT_TOP | DT_SINGLELINE); } else { DoSuperclassPaint(pdc, rcBounds); }
为控件类头文件的头文件的公用部分,为成员变量添加以下定义 (构造函数) :
CString m_strText; short m_nMyNum;
使以下一行作为 DoPropExchange 函数的最后一行:
PX_String(pPX, _T("MyProp"), m_strText);
修改 OnResetState 函数,使其包含以下代码:
COleControl::OnResetState(); // Resets defaults found in DoPropExchange m_strText = AmbientDisplayName();
修改 GetMyProp 函数,使其包含以下代码:
if(AmbientUserMode()) { GetWindowText(m_strText); m_nMyNum = (short)_ttoi(m_strText); } return m_nMyNum;
现在可以生成项目,将注册控件。 在在对话框中插入控件,Data Field 和 Data Source (数据源) 属性已添加,并且您可以选择一个数据源和字段在控件中显示。