前言:在项目中碰到问题,要求用到listview显示数据,前面还需要提供按钮进行对某行数据选中(需求样式如下图:通过和UI协商,我才用了check控件)
大家都知道多个check在一起是独立的,不受影响,那么怎样使按钮可以支持单选呢?
先看看listview的xml文件:
<listview pos="58,76,@448,@188" name="lv_mission_list" dividerSize="5" wantTab="1" font="adding:-4" show="1">
<template itemHeight="30" colorHover="#dcf0f1" colorSelected="#dcf0f1" trackMouseEvent="0" >
<window colorBkgnd="#A9A9A9" pos="99,[0,@1,@35" />
<check id="1" pos="38,8" name="check_choose_mission"/>
<window colorBkgnd="#A9A9A9" pos="249,0,@1,@35" />
<text id="2" pos="100,5" height="20" width="148" font="face:微软雅黑:adding:-2" name="text_choose_mission_time" align="center" dotted="1" show="1">123456</text>
<text id="3" pos="251,5" height="20" width="182" font="face:微软雅黑:adding:-2" name="text_choose_mission_name" align="center" dotted="1" show="1">123456</text>
<window colorBkgnd="#A9A9A9" pos="0,32,@450,@1" />
</template>
</listview>
这就需要用代码去限制了(直接上代码,语言表达能力弱,各位大神指点批评)
ListViewAdapter.h
#pragma once
#include "stdafx.h"
#include <iostream>
class CScanMissionListAdapter : public SOUI::SAdapterBase
{
public:
CScanMissionListAdapter();
virtual ~CScanMissionListAdapter();
// 定义列表项目个数
virtual int getCount() override;
// 绘制每一行的样式
virtual void getView(int position, SOUI::SWindow* pItem, pugi::xml_node xmlTemplate) override;
// 初始化每一行的样式
void _InitView(int position, SOUI::SWindow* pItem);
// 勾选触发函数
bool OnCheckClick(SOUI::EventArgs *pEvt);
private:
int* m_pCbxSel;
INT m_nCurCheck;
};
ListViewAdapter.cpp
#include "stdafx.h"
#include "ListViewAdapter.h"
CScanMissionListAdapter::CScanMissionListAdapter() : m_nCurCheck(-1)
{
m_pCbxSel = new int[getCount()];
memset(m_pCbxSel, 0, sizeof(int)*getCount());
}
CScanMissionListAdapter:: ~CScanMissionListAdapter()
{
delete[] m_pCbxSel;
}
// 定义列表项目个数
int CScanMissionListAdapter::getCount()
{
return 6;
}
// 绘制每一行的样式
void CScanMissionListAdapter::getView(int position, SOUI::SWindow* pItem, pugi::xml_node xmlTemplate)
{
if (pItem->GetChildrenCount() == 0)
{
pItem->InitFromXml(xmlTemplate);
}
_InitView(position, pItem);
}
// 初始化每一行的样式
void CScanMissionListAdapter::_InitView(int position, SOUI::SWindow* pItem)
{
SOUI::SWindow *pCheck = pItem->FindChildByID(1);
if (pCheck != NULL)
{
// 设置当前行号到 check 控件中去
pCheck->SetUserData(position);
// 绑定触发函数
pCheck->GetEventSet()->subscribeEvent(SOUI::EVT_CMD,
Subscriber(&CScanMissionListAdapter::OnCheckClick, this));
// 勾选当前选中行
pCheck->SetCheck(m_nCurCheck == position ? TRUE : FALSE);
}
}
// 勾选触发函数
bool CScanMissionListAdapter::OnCheckClick(SOUI::EventArgs *pEvt)
{
// 从 UserData 中读取到当前被勾选的行号,存储到 m_nCurCheck 中去
// 以便 getView 刷新后重设样式
SOUI::SCheckBox* pCheck = SOUI::sobj_cast<SOUI::SCheckBox>(pEvt->sender);
if (pCheck != NULL)
{
m_nCurCheck = pCheck->GetUserData();
}
// 刷新当前的 listview,自动调用 getView 函数,重新绘制样式
notifyDataSetChanged();
return false;
}
最后结果如图: