MFC ActiveX 控件:在 ActiveX 控件中使用数据绑定

ActiveX 控件功能更强大的用途之一是数据绑定,它允许控件的属性与数据库中的特定字段绑定。 当用户修改此绑定属性中的数据时,该控件会通知数据库并请求更新记录字段。 然后,数据库会通知控制请求的成功或失败。

重要

ActiveX 是一项不推荐用于新开发的旧技术。 有关取代 ActiveX 的新式技术的详细信息,请参阅 ActiveX 控件

本文介绍任务的控制方面。 实现与数据库的数据绑定交互是控制容器的责任。 如何在容器中管理数据库交互超出了本文档的范围。 本文的其余部分介绍了如何为数据绑定准备控件。

数据绑定控件的概念图。
Data-Bound 控件的概念图

COleControl 类提供两个成员函数,使数据绑定成为实现的简单过程。 第一个函数 BoundPropertyRequestEdit 用于请求更改属性值的权限。 成功更改属性值后,将调用第二个函数 BoundPropertyChanged

本文涵盖以下主题:

创建可绑定的常用属性

尽管你可能更需要可绑定的 Get/Set 方法,但创建数据绑定常用属性是可能的。

注释

默认情况下,库存属性具有 bindablerequestedit 属性。

使用“添加属性向导”添加可绑定的常用属性

  1. 使用 MFC ActiveX 控件向导开始项目。

  2. 右键单击控件的接口节点。

    这将打开快捷菜单。

  3. 在快捷菜单中,单击“ 添加 ”,然后单击“ 添加属性”。

  4. “属性名称” 下拉列表中选择其中一个条目。 例如,可以选择 “文本”。

    由于 Text 是一个默认属性,因此已检查 可绑定requestedit 属性。

  5. IDL 属性选项卡中选中以下复选框:displaybinddefaultbind,以将这些属性添加到项目的 .IDL 文件中的属性定义里。 这些属性使控件对用户可见,并使库存属性成为默认可绑定属性。

此时,控件可以显示数据源中的数据,但用户将无法更新数据字段。 如果希望控件也能更新数据,请更改 OnOcmCommandOnOcmCommand 函数,如下所示:

#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 控件进行子类化。

使用“添加属性向导”添加可绑定的获取/设置方法

  1. 加载控件的项目。

  2. “控件设置” 页面上,选择一个窗口类,用于对控件进行子类化。 例如,你可能想要将 EDIT 控件子类化。

  3. 加载控件的项目。

  4. 右键单击控件的接口节点。

    这将打开快捷菜单。

  5. 在快捷菜单中,单击“ 添加 ”,然后单击“ 添加属性”。

  6. “属性名称 ”框中键入属性名称。 使用 MyProp 做此示例。

  7. “属性类型” 下拉列表框中选择数据类型。 使用 short 做此示例。

  8. 对于 实现类型,请单击 “获取/设置方法”。

  9. 从 IDL 属性选项卡中选中以下复选框:bindablerequesteditdisplaybinddefaultbind,以将这些属性添加到项目的 .IDL 文件的属性定义中。 这些属性使控件对用户可见,并使库存属性成为默认可绑定属性。

  10. 单击“完成”。

  11. 修改函数的 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();
    }
    
  12. 传递给 BoundPropertyChangedBoundPropertyRequestEdit 函数的参数是属性的 dispid,它是传递给 .IDL 文件中属性的 id() 特性的参数。

  13. 修改 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;
    
  14. 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);
    }
    
  15. 在头文件的公共部分(即控件类的头文件)中,为成员变量添加以下定义(构造函数):

    CString m_strText;
    short m_nMyNum;
    
  16. 将以下行设为函数中的 DoPropExchange 最后一行:

    PX_String(pPX, _T("MyProp"), m_strText);
    
  17. OnResetState修改函数,使其包含以下代码:

    m_strText = AmbientDisplayName();
    m_strText = AmbientDisplayName();
    
  18. GetMyProp修改函数,使其包含以下代码:

    if (AmbientUserMode())
    {
       GetWindowText(m_strText);
       m_nMyNum = (short)_ttoi(m_strText);
    }
    return m_nMyNum;
    

现在可以生成项目,该项目将注册控件。 在对话框中插入控件时,将添加 “数据字段 ”和 “数据源 ”属性,现在可以选择要在控件中显示的数据源和字段。

另请参阅

MFC ActiveX 控件