Is there a dual function for ListBox.IndexFromPoint(Point p)?

G

Guest

I'm writing a poor man's browser using an owner drawn ListBox. I was
positioning the ListBox items (Controls) using Control.Location until I
discovered that Control.Location has the seemingly retarded limitation of
32767 (2^16 signed integer). I had been mapping viewport coordinates to real
(logical coordinates) and vice versa when translating mouse event coordinates
for hit testing and when mapping real logical coordinates to viewport
coordinates in painting. However upon discovering the 16 bit limitation of
Control.Location I've decided to ignore that items' Location property and
simply use the ListBox.IndexFromPoint(Point p) method in dispatching mouse
events and DrawItemEventArgs.Bounds in paint events.
In order to translate the mouse event coordinates that are in viewport
coordinates to a coordinate relative to the ListBox item clicked on and which
is the ListBox item retrieved via a call to:
ListBox.IndexFromPoint(mouseLoc);
the viewport coordinate of this same item is needed. Is there a way to get
that viewport coordinate? This is necessary in order to recursively find the
deepest child at a given point (assuming no overlapping children -- i.e. no
z-order of children):

<code>
private static Control FindDeepestAtPoint(Control ctrl,Point pt)
{
Control child = ctrl.GetChildAtPoint(pt);
if (child != null)
{
//map coordinates to be local to child
pt.Offset(-child.Location.X, -child.Location.Y);
return FindDeepestAtPoint(child, pt);
}
return ctrl;
}
</code>

So in summary, is there a way to get the viewport coordinates of a visible
item in a ListBox, and more specifically is there a way to get the viewport
coordinates of a visible item in a ListBox in C# which has been clicked on
and for which ListBox.IndexFromPoint(Point p) has returned the item in
question whose viewport coordinates are desired?
 
G

Guest

Actually the answer was quite easy:

<code>
private int ItemViewportY(int iItem)
{
//since topItem's viewport coordinates are (0,0),
//then the item clicked on will have coordinates offset
//from this by the sum of the heights of items between
//the topItem and the item clicked on:
int iItemY = 0;
for (int i = listBox.TopIndex; i < iItem; i++)
{
iItemY += ((Control)listBox.Items).Height;
}
return iItemY;
}
</code>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top