TreeView控件能够清晰地表示层次关系在TreeView编程中常见的一个问题是同步选择(即选择一个节点时同时选择该节点的所有子节点不选一个节点同时去除该节点的祖先节点选择标志)
要实现这种效果本来不难只需要在检测到节点选择状态变化时遍历节点的祖先或者后代节点进行同步即可但是PB并没有提供检测节点选择状态变化的事件
让我们来看看PB中TreeView节点选择状态的表示当TreeView的CheckBoxes属性为True时每个节点包含一个复选框选中复选框时StatePictureIndex属性为未选中则为当选择某个节点时首先触发TreeView的Clicked事件处理完Clicked事件后再对StatePictureIndex进行设置显然如果我们能够将Clicked事件前后节点的StatePictureIndex属性值进行比较我们就可以判断节点的选择状态是否发生了变化按照这个思路疏理PB的事件模型发现采用Post的调用事件方法可以实现将一个事件加入控件消息序列在处理完当前事件后再对新加入的事件进行处理
至此我们得到了如下的解决方案
为TreeView控件添加一个用户事件ue_synchronizechildren(long handle integer state)
代码如下
long childitem
treeviewitem tvitem
getitem(handle tvitem)
tvitemstatepictureindex=state
setitem(handle tvitem)
childitem=thisfinditem(ChildTreeItem! handle)
do while(childitem<>)
thisEvent ue_synchronizechildren(childitem state) //递归遍历后代结点
childitem=thisfinditem(NextTreeItem! childitem)
loop
添加一个用户事件ue_synchronizeparent(long handle integer state)如下
long parentitem
treeviewitem tvitem
getitem(handle tvitem)
tvitemstatepictureindex=state
setitem(handle tvitem)
parentitem=thisfinditem(ParentTreeItem! handle)
if parentitem<> then
thisEvent ue_synchronizeparent(parentitem state)
end if
添加一个用户事件ue_statechanged(long handle integer prevstate)检测节点的选择状态 如果发生了变化则调用ue_synchronizechildren同步后代节点并根据需要通过ue_synchronizeparent同步祖先节点
代码如下
treeviewitem tvitem
getitem(handle tvitem)
if tvitemstatepictureindex=prevstate then
return
else
thisEvent ue_synchronizechildren(handle tvitemstatepictureindex)
if tvitemstatepictureindex= then //如需实现文末提及的功能可在此处添加代码
thisEvent ue_synchronizeparent(handle tvitemstatepictureindex)
end if
end if
在Clicked事件中添加如下调用
treeviewitem tvitem
getitem(handle tvitem)
post event ue_statechanged(handle tvitemstatepictureindex)
为了简单起见上面的代码并没有考虑当选上一个结点时它的所有兄弟已被选择因此父结点也应该被选择的情况如有需要请读者自己完成