ActiveX 控件功能更强大的用途之一是数据绑定,它允许控件的属性与数据库中的特定字段绑定。 当用户修改此绑定属性中的数据时,该控件会通知数据库并请求更新记录字段。 然后,数据库会通知控制请求的成功或失败。
重要
ActiveX 是一项不推荐用于新开发的旧技术。 有关取代 ActiveX 的新式技术的详细信息,请参阅 ActiveX 控件。
本文介绍任务的控制方面。 实现与数据库的数据绑定交互是控制容器的责任。 如何在容器中管理数据库交互超出了本文档的范围。 本文的其余部分介绍了如何为数据绑定准备控件。
Data-Bound 控件的概念图
该 COleControl
类提供两个成员函数,使数据绑定成为实现的简单过程。 第一个函数 BoundPropertyRequestEdit 用于请求更改属性值的权限。 成功更改属性值后,将调用第二个函数 BoundPropertyChanged。
本文涵盖以下主题:
创建可绑定的常用属性
尽管你可能更需要可绑定的 Get/Set 方法,但创建数据绑定常用属性是可能的。
注释
默认情况下,库存属性具有 bindable
和 requestedit
属性。
使用“添加属性向导”添加可绑定的常用属性
使用 MFC ActiveX 控件向导开始项目。
右键单击控件的接口节点。
这将打开快捷菜单。
在快捷菜单中,单击“ 添加 ”,然后单击“ 添加属性”。
从 “属性名称” 下拉列表中选择其中一个条目。 例如,可以选择 “文本”。
由于 Text 是一个默认属性,因此已检查 可绑定 和 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;
现在可以生成项目,该项目将注册控件。 在对话框中插入控件时,将添加 “数据字段 ”和 “数据源 ”属性,现在可以选择要在控件中显示的数据源和字段。
创建可绑定的 Get/Set 方法
除了数据绑定 get/set 方法之外,还可以创建 可绑定的股票属性。
注释
此过程假定你有一个 ActiveX 控件项目,该项目对 Windows 控件进行子类化。
使用“添加属性向导”添加可绑定的获取/设置方法
加载控件的项目。
在 “控件设置” 页面上,选择一个窗口类,用于对控件进行子类化。 例如,你可能想要将 EDIT 控件子类化。
加载控件的项目。
右键单击控件的接口节点。
这将打开快捷菜单。
在快捷菜单中,单击“ 添加 ”,然后单击“ 添加属性”。
在 “属性名称 ”框中键入属性名称。 使用
MyProp
做此示例。从 “属性类型” 下拉列表框中选择数据类型。 使用
short
做此示例。对于 实现类型,请单击 “获取/设置方法”。
从 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
函数的参数是属性的 dispid,它是传递给 .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
修改函数,使其包含以下代码:m_strText = AmbientDisplayName(); m_strText = AmbientDisplayName();
GetMyProp
修改函数,使其包含以下代码:if (AmbientUserMode()) { GetWindowText(m_strText); m_nMyNum = (short)_ttoi(m_strText); } return m_nMyNum;
现在可以生成项目,该项目将注册控件。 在对话框中插入控件时,将添加 “数据字段 ”和 “数据源 ”属性,现在可以选择要在控件中显示的数据源和字段。