65.9K
CodeProject 正在变化。 阅读更多。
Home

WTL 虚拟列表控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (24投票s)

2011 年 6 月 28 日

CPOL

3分钟阅读

viewsIcon

55825

downloadIcon

4274

WTL Windows 列表视图控件的数据绑定扩展。

引言

这是 WTL (Windows 模板库) 的 CListViewCtrl 的扩展。它支持在 OLEDB 源和放置在视图窗口或对话框上的虚拟列表视图控件之间交换大多数 OLEDB 数据类型(不包括 blob 类型)。它使用 MS SQL Server 开发和测试,但应该适用于任何可访问 OLEDB 的数据库。

Sample application using a view window

开发环境

此模板与 WTL 8.0 兼容,示例在 Visual Studio 2008 中创建。但是,通过进行少量修改,应该可以支持早期版本的 WTL 和 VS。

背景

WTLVirtualList 将 OLEDB 消费者与所有者提供的数据 (LVS_OWNERDATA) 报告样式列表视图控件连接起来。一个处理程序响应 LVN_GETDISPINFO 消息提供数据。此控件使用消费者提供的列名动态创建列表视图列,并响应双击子项显示一个就地编辑控件。它支持用于行标识和操作的书签,并提供用于常见操作(如移动、添加和删除)的菜单处理程序。列数据编辑通过就地编辑控件完成。

使用代码

在您的应用程序中使用此类的起点是为您的数据库表生成一个 OLEDB 消费者类。有关如何使用 ATL 对象向导创建 OLEDB 消费者类的详细信息,请参阅 WTL OLEDB 数据库应用程序简介。按照以下概述对您的消费者类进行一些简单的修改以支持书签功能。下载示例项目,如果需要帮助,请查阅 Titles.hCustomers.h 文件。

  1. 添加 CBookmark<4> m_Bookmark;DBSTATUS m_dwBookmarkStatus; 作为成员变量
  2. GetRowsetProperties 函数中添加 pPropSet->AddProperty(DBPROP_IRowsetLocate, true, DBPROPOPTIONS_OPTIONAL);
  3. 在列映射中添加 BOOKMARK_ENTRY_STATUS(m_Bookmark, m_dwBookmarkStatus)

在 MainFrm 或 MainDlg 中添加一个成员变量

创建并修改您的消费者后,您需要在您的项目中添加 WTLVirtualList 头文件,并在您的对话框或框架中添加 CWTLVirtualList<Cxxxxx> m_view; 成员变量(用您的消费者类名替换 xxxxx)。 视图窗口的初始化是自动处理的,但请确保将 REFLECT_NOTIFICATIONS() 添加到主框架消息映射中。

基于对话框的应用程序

您需要使用资源编辑器将列表视图控件添加到您的对话框中,然后在 OnInitDialog 中放置以下代码来初始化虚拟列表视图。

// Initialize the virtual list view
m_view.Init(GetDlgItem(IDC_LIST1));

// Set first visible column width. Needed because the default
// width is set to the control's width on the dialog
int col = 0;
if (!m_view.GetShowBookmarks()) col = 1;
m_view.SetColumnWidth(col, LVSCW_AUTOSIZE_USEHEADER);

// Set the background color of alternating rows
m_view.SetBarColor(BLUEBAR);

菜单或按钮映射

您还需要将命令处理程序添加到消息映射中,如果需要,还需要覆盖数据命令的事件处理程序。如上所述,虚拟列表类在 CLVMenuCommands 中包含一组默认的菜单标识符和事件处理程序,用于处理普通数据功能。如果需要在插入新记录时设置键和/或默认值,则需要覆盖默认处理程序。例如

LRESULT OnDataNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
    m_view.m_data.ClearRecordMemory(); // Sets all values to 0

    // Example of how to set your own data values. Make sure to initialize any
    // key values and non-null fields before Insert is called. After this, non-
    // mandatory values can be entered in the listview for each column
    TCHAR* CustomerID = _T("ZZ997"); // dummy key value
    _tcsncpy_s(m_view.m_data.m_CustomerID, _tcslen(CustomerID) + 1, CustomerID, _TRUNCATE);

    // Call the base handler to do the actual insert
    return m_view.OnDataNew(wNotifyCode, wID, hWndCtl, bHandled);
}

属性

  • Get/SetBarColor - 交替数据行的颜色。选项有 NOBAR, BLUEBAR, GRAYBAR, GREENBARREDBAR,但您可以将任何想要的颜色添加到枚举中。
  • Get/SetReadOnly - 数据可以被修改或不被修改。
  • Get/SetShowBookmarks - 书签是一个内部行 ID。此 ID 仅限于消费者表示,并且独立于数据中的任何键值。
  • Get/SetSingleSelect - 可以选择一行或多行。

幕后

WTLVirtualList 使用 LVN_GETDISPINFO 通知处理程序来同步屏幕上数据的显示与从数据源获取数据,并使用转换函数 (OledbToString) 格式化数据以显示在列表视图中。初始加载和滚动是数据获取的常见触发器。

// This function is called when the list needs database data for items
// that are displayed in the visible portion of the virtual list
LRESULT OnLVGetDispInfo(int, LPNMHDR pNMHDR, BOOL&)
{
    if (pNMHDR->hwndFrom != m_hWnd) return 0;

    // Clear the list if a data acquisition error is encountered.
    if (!IsValidRow()) return SetRowCount();

    // Create a pointer to the item that needs data
    LVITEM* pItem = &((NMLVDISPINFO*)pNMHDR)->item;
    if (pItem->mask & LVIF_TEXT)
    {
        // Obtain the data for the virtual listview control
        if (pItem->iSubItem == 0) // Bookmark
        {
            ULONG row = SetActiveRow(pItem->iItem);
            _ltot_s(row, pItem->pszText, MAXOLEDBNUM, 10);
        }
        else OledbToString(m_prgBindings[pItem->iSubItem], pItem->pszText); // Data
    }

    return 0;
}

NM_CUSTOMDRAW 的处理程序绘制交替行颜色,并且可以扩展以支持其他视觉修饰。此外,还有用于鼠标点击、编辑控件和滚动条的处理程序,以支持这些功能。

关于示例

对话框应用程序使用 Pubs 数据库中的 titles 表,而视图应用程序使用 Northwind 中的 customers 表。您要么需要访问具有这些数据库的数据库服务器才能使用这些示例,要么为您的特定表生成一个消费者类并将其添加到项目中。您可能还需要修改消费者类中的连接字符串以指向您的数据库。它们当前设置为 localhost,并使用集成安全性。

© . All rights reserved.