Chapter 165 · XUI 数据录入控件

Cascader 级联选择

Cascader 多级级联选择器,支持树形数据、路径选择、全级显示、弹出面板。

165

概念

Cascader 用于多级关联选择(如省→市→区):
• 树形数据:xui_cascader_item_t 描述 parent→child 关系
• 路径选择:选中结果为从根到叶的值数组
• ShowAllLevels:输入框显示完整路径或仅叶节点
• 弹出面板:多列并排展示各级选项

API 速查

函数说明
int xuiCascaderCreate(xui_context pCtx, xui_widget* ppW, const xui_cascader_desc_t* pDesc)创建级联选择
int xuiCascaderSetItems(xui_widget pW, const xui_cascader_item_t* pItems, int iCount)设置数据源
int xuiCascaderSetSelectedPath(xui_widget pW, const int* arrValues, int iDepth)设置选中路径
int xuiCascaderGetSelectedPath(xui_widget pW, int* arrValues, int iCapacity)获取选中路径
int xuiCascaderGetSelectedDepth(xui_widget pW)选中深度
int xuiCascaderGetSelectedLeaf(xui_widget pW)叶节点值
int xuiCascaderSetShowAllLevels(xui_widget pW, int bShowAll)显示全路径
int xuiCascaderOpen(xui_widget pW)打开面板
int xuiCascaderClose(xui_widget pW)关闭面板
int xuiCascaderClear(xui_widget pW)清除选择
int xuiCascaderSetChange(xui_widget pW, xui_cascader_change_proc onChange, void* pUser)变更回调

编译本章示例

gcc -O2 -I. -o ch165.exe ch165_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch165.exe

示例:地区选择

xui_cascader_desc_t desc = { 0 };

xui_widget pCascader;
xuiCascaderCreate(pCtx, &pCascader, &desc);

// 构建数据:value / parentValue / text
xui_cascader_item_t items[] = {
    { 1, 0, "广东" },
    { 2, 0, "浙江" },
    { 10, 1, "广州" },
    { 11, 1, "深圳" },
    { 20, 2, "杭州" },
};
xuiCascaderSetItems(pCascader, items, 5);
xuiCascaderSetShowAllLevels(pCascader, 1);

// 默认选中:广东→深圳
int path[] = { 1, 11 };
xuiCascaderSetSelectedPath(pCascader, path, 2);

xuiCascaderSetChange(pCascader, OnRegionChange, NULL);

完整代码

将以下代码保存为 ch165_main.c,编译后运行即可看到 Cascader 级联选择效果:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;

static void OnRegionChange(xui_widget pW, void* pUser) {
    (void)pUser;
    int leaf = xuiCascaderGetSelectedLeaf(pW);
    xgeLogWrite("选中地区叶节点: %d", leaf);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xui_vec2_t pos; xgeMouseGet(&pos.x, &pos.y);
    xuiInputPointerMove(g_pCtx, pos.x, pos.y);
    if (xgeMouseDown(XGE_MOUSE_LEFT)) xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
    else xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth = 800; d.iHeight = 600;
    d.sTitle = "ch165 - Cascader";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);
    xuiCreate(&g_pCtx);
    /* XGE 官方代理由 xuiProxyXge() 提供 */
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    xui_widget pRoot;
    xuiPanelCreate(g_pCtx, &pRoot, NULL);
    xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});

    /* 级联选择 */
    xui_cascader_desc_t casDesc = {0};
    xui_widget pCascader;
    xuiCascaderCreate(g_pCtx, &pCascader, &casDesc);
    xuiWidgetSetRect(pCascader, (xui_rect_t){0, 0, 220, 32});
    xuiWidgetSetRect(pCascader, (xui_rect_t){290, 200, 220, 32});

    xui_cascader_item_t items[] = {
        { 1, 0, "广东" },
        { 2, 0, "浙江" },
        { 10, 1, "广州" },
        { 11, 1, "深圳" },
        { 20, 2, "杭州" },
        { 21, 2, "宁波" },
    };
    xuiCascaderSetItems(pCascader, items, 6);
    xuiCascaderSetShowAllLevels(pCascader, 1);
    xuiCascaderSetChange(pCascader, OnRegionChange, NULL);
    xuiWidgetAddChild(pRoot, pCascader);

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiCascaderCreate:创建级联选择器控件。
  • xui_cascader_item_t:每项包含 value、parentValue、text,parentValue=0 表示顶级。
  • SetShowAllLevels(1):输入框显示完整路径(如“广东 / 深圳”)。
  • GetSelectedLeaf:回调中获取最深层选中值。
  • 弹出面板:点击控件后多列并排展示各级选项。

要点与陷阱

  • ParentValue=0:表示顶级节点(根)。
  • Path:选中路径是 value 数组,非索引数组。
  • Leaf:GetSelectedLeaf 返回最深层选中值。
  • Clear:清除后 Depth=0,输入框显示 Placeholder。

进阶练习

  1. 分类选择:商品三级分类(大类→中类→小类)。
  2. 动态加载:选择一级后异步加载二级数据。
Cascader 级联选择效果
图:Cascader 级联选择渲染效果