There is a way to do it with a bound scrollbar but it has some limitations. First, the mechanism uses an undocumented aspect of the listbox items' properties (since it's undocumented, the devs could theoretically change the way it behaves without notice) - the Top property of an item in a listbox with a bound scrollbar will change as the scrollbar scrolls. Second, there is no way to force a bound scrollbar to scroll, so instead this method changes the listbox selection since the listbox will automatically scroll the selected item into view.
The following sample assumes you have a window with a listbox, "self.EList" (this happens to be the actual name of an object where I used this mechanism). Then where ever in the code that you add an item to the list box, you just check whether the list box is scrolled to the bottom by checking the height of the highest indexed item in the listbox against the listbox's height. If the listbox was scrolled to the bottom, then after you add the new item, just set the selection to the highest indexed item and it will automatically scroll to the bottom.
Here's the relevant code from an actual plugin:
Note that I use <= in the comparison because sometimes the GetTop() method will return 0 even though the item added has been scrolled.
if self.EList:GetItemCount()>0 then
if isMaxIndex then