开发者

Get the scroll position from a RichTextBox?

I've created a highlighting mechanism for a RichTextBox in Silverlight 4. It'll get character positions and draw rectangle(s) over the text.

The trouble I ha开发者_如何学JAVAve now is with scrolling on the RichTextBox. As I scroll all of my precious highlighting gets left behind. Is there any way I can add an event handler to a scroll event and/or a scrolling position of the RichTextBox? Or is there some better way in which I can link the position of the highlighting rectangles to the RichTextBox?


The trick would be to get what ever panel (I guess its a Canvas?) that you are overlaying the RichTextBox with to actually exist within the same ScrollViewer that rich text exists in.

The following is very rough idea but should get you on the path to reasonable solution.

You can do this using a custom style for the RichTextBox. The default style for this control can be found here.

Copy this style into a resource in your containing UserControl and point your RichTextBox Style property at it. So far nothing is different but now you can play about with the template. The relevant portion currently looks like this:-

<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
    <ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False" />
</Border>

Now we can tweak it like this:-

<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
    <ScrollViewer Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False">
        <Grid>
            <ContentControl x:Name="ContentElement" />
            <Canvas x:Name="HighlightOverlay" />
        </Grid>
    </ScrollViewer>
</Border>

You'll note that we've moved the name "ContentElement" from the ScrollViewer to the new ContentControl. Having a FrameworkElement called "ContentElement" is the only feature that the RichTextBox stipulates about its template.

Now overlaying this ContentControl we can place a Canvas where you can place your highlighting rectangles. If the user scrolls this RichTextBox the whole Grid containing both the Content and the Highlights will scroll together.

The only remaining trick is acquiring the "HighlightOverlay" so that you can add your rectangle to it. Here is some code that will grab it:-

    private Canvas HightlightOverlay;
    public MyUserControl()
    {
        InitializeComponent();
        MyRichText.LayoutUpdated += MyRichText_LayoutUpdated;
    }

    void MyRichText_LayoutUpdated(object sender, EventArgs e)
    {
        HightlightOverlay = MyRichText.Descendents()
            .OfType<Canvas>()
            .FirstOrDefault(elem => elem.Name == "HighlightOverlay");
    }

You will be wondering where the Descendents method is coming from, it is here.


Anthony W Jones came up with a brilliant solution. There were just a couple tweaks to the XAML I had to make.

As suggested I started with this inside the template:

<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
    <ScrollViewer Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False">
        <Grid>
            <ContentControl x:Name="ContentElement" />
            <Canvas x:Name="HighlightOverlay" />
        </Grid>
    </ScrollViewer>
</Border>

But the ContentControl messed things up somehow and you can't actually type into the RichTextBox anymore. Also, the scroll bars weren't showing up.

But I found the two changes necessary to make this work:

<Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1">
    <ScrollViewer BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Grid>
            <Grid x:Name="ContentElement" />
            <Canvas x:Name="HighlightOverlay" />
        </Grid>
    </ScrollViewer>
</Border>

Adding HorizontalScrollBarVisibility="Auto" and VerticalScrollBarVisibility="Auto" brought the scroll bars back, and simply using Grid instead of the ContentControl made the RichTextBox editable again.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜