If the Vendor object can only hold a single Bucket object it may be appropriate to bind it all in a single, top-level repeater. You can access the Bucket through simple data-binding all at the top level without overriding ItemDataBound.
Because you're most likely binding the "Vendor", you have access to it's members in a databind if you want to do it this way:
<%# DataBinder.Eval (Container.DataItem, "Bucket.Property" ) %>
You want to do the ItemDataBound if you must "process something" during each iteration of the binding and need detailed access to each Vendor object for decision making.
If the Vendor object can hold multiple Buckets, then the best way to get access to that is through ItemDataBound. On each iteration of the Vendor you could bind a new, nested repeater to display the bucket data, or perform whatever repeating/aggregation functionality you may need.
Depending on how you want it to behave at your client, you could render the Vendors only. When the user clicks on the Vendor (or whatever), you could perform an AJAX call to the server which would retrieve the Bucket data and render it into your page dynamically. You may want to try that approach if there are a large number of vendors along with their buckets being rendered. This would help database performance, and page render time in contrast to building it all on the ASPX server side. (But this would need to be a lot of data, you should do it for usability/client reasons before trying to merit performance gains.)