Hi,
I have built a form with an ultratreeview and an ultralistview. On mouseup on an active node the listview is updated. I have more events defined on the treeview like mousedown and mousemove. It seems necessary to use the refresh method on the listview after the update is done, otherwise the updates are sometimes shown after a remarkable period of time or after a mousemove. Is this use of the refresh method some sort of "known good practise"?
UltraListView automatically updates itself when (for example) a relevant property changes, or when you repopulate it. Assuming by a "remarkable" period of time you mean more than a few milliseconds, I'm not sure what is causing that, unless by chance you are inadvertantly supressing painting by calling BeginUpdate on the control. If you can, post a simple sample and we can take a look.
The Refresh method invalidates the entire control and then sends a WM_PAINT message to it, causing the entire control to be repainted. This can have performance ramifications if you use it frequently, but if you call it (for example) after repopulating the entire control, I would consider that to be a valid use of it. As I stated in the previous paragraph, however, it should not be necessary.
It is much more than a few milliseconds. Here is the code (language = progress), the seemingly necessary refresh follows listview:EndUpdate():
listview:BeginUpdate().
if pcParentNodeKey = '' /* first call, from */ then do:
assign listview:MainColumn:Text = "Caption"
listview:MainColumn:Width = 100
SubItemColumn = NEW UltraListViewSubItemColumn()
SubItemColumn:Width = 300
SubItemColumn:Text = "Action".
listView:SubItemColumns:Add(SubItemColumn).
assign SubItemColumn = NEW UltraListViewSubItemColumn()
SubItemColumn:Width = 200
SubItemColumn:Text = "Menutype".
find first bufMenuset no-error.
if available bufMenuset then pcParentNodeKey = bufMenuset.MenuSetId.
end.
mdMenu:getIds(pcParentNodeKey,output cMenuSetId, output cParentMenuObjectId, output cMenuObjectId).
listview:Items:Clear().
if treeview ne ? then do:
/* assign the 'opened' image to the parentnode and reassign the former closed nodeimage to the former opened node */
if hPreviousParentNode ne ? then hPreviousParentNode:Override:NodeAppearance:Image = hPreviousImage.
assign
hParentNode = treeview:GetNodeByKey(pcParentNodeKey)
hPreviousImage = cast(hParentNode:Override:NodeAppearance:Image, Image)
hParentNode:Override:NodeAppearance:Image = if cMenuObjectId ne '':U then hImageFolderOpen else hImageMenuSetOpen
hPreviousParentNode = hParentNode.
for each bufLink
where bufLink.MenusetId = cMenuSetId
and bufLink.parentMenuObjectId = cMenuObjectId,
first bufObject
where bufObject.menuObjectId = bufLink.menuObjectId
by bufLink.MenuOrder
on error undo, throw:
subItem[1] = new UltraListViewSubItem()
subItem[1]:Value = bufObject.MenuAction
subItem[2] = new UltraListViewSubItem()
subItem[2]:Value = bufObject.MenuType
hItem = new UltraListViewItem(hObject, SubItem)
hItem:Value = bufObject.Caption
hItem:Appearance:Image = if bufObject.MenuCategory = 'Controller':U then hImageControl
else if bufObject.MenuType = 'Rule':U then hImageRule
else hImageFolder
hItem:Key = cMenuSetId + chr(1) + cMenuObjectId + chr(1) + bufLink.menuObjectId.
listview:Items:add(hItem).
end. /* for each bufLink */
listview:EndUpdate().
listview:Refresh().
I'm not familiar with this language but the EndUpdate method causes invalidation of the entire control, so you probably need to call the Update method (Refresh invalidates and updates but the control will have already been invalidated at that point) to trigger a synchronous repainting.