Determining the tapped paragraph using the 'DoubleTapped' event on RichTextBlock

95 Views Asked by At

I'm trying to do something along the lines of a paragraph-based interaction, like many ebook readers do (they let you click a paragraph and show a small menu with a few options etc).

The thing I'm stuck on is determining a paragraph clicked/tapped by the user. The events can't be assigned directly to Block type objects, so I tried working around it by attaching a DoubleTapped event handler to the parent RichTetBlock. I was thinking that it might be somehow possible to determine the paragraph based on position, but I'm not exactly sure how to go about it in practice.

What I've got so far:

this.chapterText.AddHandler(DoubleTappedEvent, new DoubleTappedEventHandler(chapterText_DoubleTapped), true);
...
private void chapterText_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
    var rtb = sender as RichTextBlock;
    var y = e.GetPosition(rtb).Y;
    var paragraph = rtb.Blocks.FirstOrDefault(o => y >= o.) as Paragraph;
}

But this approach clearly won't work.

Is there something I'm missing here?

Thank you!

1

There are 1 best solutions below

0
On

What I've got so far ...

You're almost there:

    private void RichTextBlock_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        RichTextBlock richTextBlock = sender as RichTextBlock;
        TextPointer textPointer = richTextBlock.GetPositionFromPoint(e.GetPosition(richTextBlock));
        Paragraph paragraph = richTextBlock.Blocks.Where(b => b.ContentStart.Offset <= textPointer.Offset && b.ContentEnd.Offset >= textPointer.Offset).FirstOrDefault() as Paragraph;
    }

or

    private void RichTextBlock_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        RichTextBlock richTextBlock = sender as RichTextBlock;
        TextPointer textPointer = richTextBlock.GetPositionFromPoint(e.GetPosition(richTextBlock));
        Run run = textPointer.Parent as Run;
        Paragraph paragraph = run.ElementStart.Parent as Paragraph;
    }

By the way, if you set the IsTextSelectionEnabled property of RichTextBlock to false, you wouldn't have to manually register the DoubleTapped event handler from code behind, it would simply work after registration in XAML:

<RichTextBlock IsTextSelectionEnabled="False" DoubleTapped="RichTextBlock_DoubleTapped">