Be Explicit
Adventures in Silverlight 4 hit-testing.

Problem:

I have misspelled words in a RichTextBox contained a DataGrid.  I want to be able to right click on it and get the suggestions.  

I use TransformToVisual on the ContextMenu with 0,0 to transform to the RichTextBox’s relative points.  I then iterate over the characters in the proper Run in the RichTextBox using GetCharacterRect and testing of the point from the ContextMenu’s point 0,0 is contained within the Rect of the character.

This all works at 100% Browser ZoomFactor.  

Now, I’m not sure if it’s a RichTextBox problem (I’ve reported a major BiDi bug to Microsoft) since it’s new or it has something to do with the DataGrid but as soon as you change the Browser’s Zoom, the system is out of wack.

By doing TransformToVisual(null).Transform(new Point()) in different levels of zoom, I saw that the ContextMenu was right but the RichTextBox is wrong.  Also, the GetCharacterRect results were following the RichTextBox, which it should.  Turns out, the difference is in the zoom factor.

Solution:

I decided to go absolute: use TransformToVisual(null) for both the ContextMenu and the RichTextBox.  I get my desired point from the ContextMenu via TransformToVisual(null).Transform(new Point()).  Then I get the Transform for the RichTextBox with TransformToVisual(null).  This is a bad transform because it doesn’t take the zoom factor into account.  I just need to change it.

TransformGroup transform = new TransformGroup();

transform.Children.Add(this.TransformToVisual(null) as Transform);

transform.Children.Add(new ScaleTransform()

{

ScaleX = 1D / Application.Current.Host.Content.ZoomFactor,

        ScaleY = 1D / Application.Current.Host.Content.ZoomFactor,

});

Now my transform is useful.  But I have to apply it to the Rects returned from TextPointer.GetCharacterRect then those Rects are correct to see if my ContextMenu’s point is in them.

I did a test project to see if the RichTextBox is at fault and it doesn’t appear to be.  Maybe it’s the DataGrid?  Maybe I’ll see another day.

Posted via email from Adam Hathcock’s Life in Software | Comment »