【问题标题】:Get the scroll position from a RichTextBox?从 RichTextBox 获取滚动位置?
【发布时间】:2011-04-08 12:16:30
【问题描述】:

我在 Silverlight 4 中为 RichTextBox 创建了高亮机制。它将获取字符位置并在文本上绘制矩形。

我现在遇到的麻烦是在 RichTextBox 上滚动。当我滚动时,我所有珍贵的突出显示都被抛在了后面。有什么方法可以将事件处理程序添加到滚动事件和/或 RichTextBox 的滚动位置?或者有没有更好的方法可以将高亮矩形的位置链接到 RichTextBox?

【问题讨论】:

    标签: silverlight silverlight-4.0 scroll richtextbox


    【解决方案1】:

    Anthony W Jones 想出了一个绝妙的解决方案。我只需要对 XAML 进行一些调整。

    按照建议,我从模板中开始:

    <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>
    

    但是 ContentControl 以某种方式把事情搞砸了,您实际上不能再输入 RichTextBox 了。此外,滚动条也没有出现。

    但我发现完成这项工作所需的两项更改:

    <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>
    

    添加HorizontalScrollBarVisibility="Auto"VerticalScrollBarVisibility="Auto" 使滚动条恢复原状,而只需使用Grid 而不是ContentControl 使RichTextBox 再次可编辑。

    【讨论】:

    • 这很奇怪,我刚刚测试了我的方法,并且该框是可编辑的,但是即使不需要它,也会出现垂直滚动条。我确实认为它需要更多的尝试才能让它以理想的方式工作。我很高兴你能成功。
    【解决方案2】:

    诀窍是让您覆盖 RichTextBox 的面板(我猜它是 Canvas?)实际存在于富文本所在的同一 ScrollViewer 中。

    以下是非常粗略的想法,但应该可以帮助您找到合理的解决方案。

    您可以使用RichTextBox 的自定义样式来执行此操作。这个控件的默认样式可以在here找到。

    将此样式复制到包含 UserControl 的资源中,并将 RichTextBox Style 属性指向它。到目前为止,没有什么不同,但现在您可以使用该模板。相关部分目前如下所示:-

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

    现在我们可以这样调整它:-

    <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>
    

    您会注意到,我们已将名称“ContentElement”从ScrollViewer 移至新的ContentControl。拥有一个名为“ContentElement”的FrameworkElement 是 RichTextBox 对其模板规定的唯一功能。

    现在覆盖这个ContentControl,我们可以放置一个Canvas,您可以在其中放置突出显示的矩形。如果用户滚动此RichTextBox,则包含内容和亮点的整个Grid 将一起滚动。

    剩下的唯一技巧是获取“HighlightOverlay”,以便您可以将矩形添加到其中。这是一些可以抓取它的代码:-

        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");
        }
    

    你会想知道Descendents方法是从哪里来的,它是here

    【讨论】:

    • 太棒了!我正要走一条完全不同的路径来实际格式化文本以完成我的突出显示,但这有其自身的问题。这非常有效,最终解决了我长期以来一直试图解决的问题。我只需要进行一些调整以使您的 xaml 工作,我将在下面添加。
    猜你喜欢
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 2010-12-22
    • 2013-09-10
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多