How to convert between various ItemSize/ImageSize units?

You can access many different font characteristics via CurrentValue. Here is an approximation to convert between ItemSize and ImageSize:

itemSize = {10, 10};
Overlay[{
  Grid[
     {{"Sample", "Text"}}, Frame -> All, Spacings -> {0, 0}, 
     ItemSize -> itemSize, Alignment -> {Left, Center}],      
  Row[{
     Framed["Sample",  ImageSize -> 
         Dynamic[itemSize*{CurrentValue["FontMWidth"], 
         CurrentValue["FontLineHeight"]}], 
         FrameMargins -> 0, FrameStyle -> Blue],
     Framed["Text", ImageSize -> 
         Dynamic[itemSize*{CurrentValue["FontMWidth"], 
         CurrentValue["FontLineHeight"]}], 
         FrameMargins -> 0, FrameStyle -> Blue]}]
}]

enter image description here


This seems to work on my system at least, but as Mr.Wizard said it might be system dependent

lineHeight = 1.5;
conversion = 10;(*magic number*)
scrollToThis = 80;
paneHeight = 200;

pos = (scrollToThis - 1/2)*lineHeight*conversion - paneHeight/2;  
Framed[ 
  Pane[
    Grid[List /@ data, Frame -> All, 
      ItemSize -> {5, lineHeight}, 
      Background -> {White, {scrollToThis -> Red}}, Spacings -> {0, 0}], 
    ImageSize -> {100, paneHeight}, Scrollbars -> {False, True}, 
    ScrollPosition -> {0, pos}, ImageMargins -> 0, FrameMargins -> 0], 
  ImageMargins -> 0, FrameMargins -> 0]

With these settings the highlighted cell always appears in the middle of the Pane independent of the values of scrollToThis, paneHeight, and lineHeight (provided lineHeight>1).

Alternatively, you could wrap each cell in the Grid in a Pane with a fixed height and use that to scroll to the right position:

scrollToThis = 80;
cellHeight = 20;
margins = 1;
width = 120;
paneHeight = 200;

gr = Grid[List[Pane[#, {width - 20, cellHeight},
       Alignment -> {Center, Center}, ImageMargins -> margins]] & /@ 
    data, 
   Frame -> All, ItemSize -> {Automatic, Automatic}, 
   Spacings -> {0, 0}, Alignment -> {Center, Center},
   Background -> {White, {scrollToThis -> Red}}];
pos = (scrollToThis - 1/2)*(cellHeight + 2 margins) - paneHeight/2;

Framed[
 Pane[gr, ImageSize -> {width, paneHeight}, 
  Scrollbars -> {False, True}, ScrollPosition -> {0, pos}, 
  ImageMargins -> 0, FrameMargins -> 0], 
 ImageMargins -> 0, FrameMargins -> 0]

It's not really the done thing to answer a question you've set a bounty on, but here is an explanation of why Mike's answer isn't quite right. The first point to note is that item sizes include the width of frames, so one needs to allow for the thickness of the frames in the ImageSize option for the second grid (thus the +2 in the option since FrameStyle has a setting including AbsoluteThickness[1] and you need to count both sides.)

It's also necessary to ensure ContentPadding is False. This affects placement of the text in the grid cell.

Finally, Row doesn't take the Spacings option while Grid does. In these circumstances it helps to used Grid for both cases. Notice I've used the Offset specification of spacing, which only counts the spacing excluding frames and borders.

Overlay[{Grid[{{"Sample", "Text"}}, Frame -> All, 
   FrameStyle -> Directive[AbsoluteThickness[1], Red], 
   Spacings -> {Offset[0], 0}, ItemSize -> itemSize, 
   Alignment -> {Left, Center}], 
  Grid[{{Framed["Sample", 
      ImageSize ->  2 + Dynamic[
         itemSize*{CurrentValue["FontMWidth"], 
           CurrentValue["FontLineHeight"]}], FrameMargins -> 0, 
      BaseStyle -> Red, 
      FrameStyle -> Directive[AbsoluteThickness[1], Blue], 
      ContentPadding -> False], 
     Framed["Text", 
      ImageSize -> 
       Dynamic[{2, 2} + 
         itemSize*{CurrentValue["FontMWidth"], 
           CurrentValue["FontLineHeight"]}], FrameMargins -> 0, 
      BaseStyle -> Red, 
      FrameStyle -> Directive[AbsoluteThickness[1], Blue], 
      ContentPadding -> False]}}, Spacings -> {Offset[0], 0}]}]

enter image description here