WPF使用TextBlock实现查找结果高亮显示

这篇具有很好参考价值的文章主要介绍了WPF使用TextBlock实现查找结果高亮显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在应用开发过程中,经常遇到这样的需求:通过关键字查找数据,把带有关键字的数据显示出来,同时在结果中高亮显示关键字。在web开发中,只需在关键字上加一层标签,然后设置标签样式就可以轻松实现。

在WPF中显示文本内容通常采用TextBlock控件,也可以采用类似的方式,通过内联流内容元素Run达到同样的效果:

<TextBlock FontSize="20">
    <Run Text="Hel" /><Run Foreground="Red" Text="lo " /><Run Text="Word" />
</TextBlock>

需要注意的是每个Run之间不要换行,如果换行的话,每个Run之间会有间隙,看起来像增加了空格。

通过这种方式实现查找结果中高亮关键字,需要把查找结果拆分成三部分,然后绑定到Run元素的Text属性,或者在后台代码中使用TextBlockInlines属性添加Run元素

textBlock1.Inlines.Add(new Run("hel"));
textBlock1.Inlines.Add(new Run("lo ") { Foreground=new SolidColorBrush(Colors.Red)});
textBlock1.Inlines.Add(new Run("world"));

这种方法虽然可以达到效果,但显然与MVVM的思想不符。接下来本文介绍一种通过附加属性实现TextBlock中指定内容高亮。
WPF使用TextBlock实现查找结果高亮显示

技术要点与实现

通过TextEffectPositionStartPositionCount以及Foreground属性设置字符串中需要高亮内容的起始位置、长度以及高亮颜色。定义附加属性允许TextBlock设置需要高亮的内容位置以及颜色。

  • 首先定义类ColoredLettering(并不要求继承DependencyObject)。
  • ColoredLettering中注册自定义的附加属性,注册附加属性方式与注册依赖属性类似,不过附加属性是用DependencyProperty.RegisterAttached来注册。
  • 给附加属性注册属性值变化事件,事件处理逻辑中设置TextEffectPositionStartPositionCount以及Foreground实现内容高亮。
public class ColoredLettering
{
    public static void SetColorStart(TextBlock textElement, int value)
    {
        textElement.SetValue(ColorStartProperty, value);
    }

    public static int GetColorStart(TextBlock textElement)
    {
        return (int)textElement.GetValue(ColorStartProperty);
    }

    // Using a DependencyProperty as the backing store for ColorStart.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ColorStartProperty =
        DependencyProperty.RegisterAttached("ColorStart", typeof(int), typeof(ColoredLettering), new FrameworkPropertyMetadata(0, OnColorStartChanged));

    private static void OnColorStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock textBlock = d as TextBlock;
        if (textBlock != null)
        {
            if (e.NewValue == e.OldValue) return;
                if (e.NewValue is int)
                {
                    int count = GetColorLength(textBlock);
                    Brush brush = GetForeColor(textBlock);
                    if ((int)e.NewValue <= 0 || count <= 0 || brush == TextBlock.ForegroundProperty.DefaultMetadata.DefaultValue) return;
                    if (textBlock.TextEffects.Count != 0)
                    {
                        textBlock.TextEffects.Clear();
                    }
                    TextEffect textEffect = new TextEffect()
                    {
                        Foreground = brush,
                        PositionStart = (int)e.NewValue,
                        PositionCount = count
                    };
                    textBlock.TextEffects.Add(textEffect);
                }
        }
    }

    public static void SetColorLength(TextBlock textElement, int value)
    {
        textElement.SetValue(ColorLengthProperty, value);
    }

    public static int GetColorLength(TextBlock textElement)
    {
        return (int)textElement.GetValue(ColorLengthProperty);
    }

    // Using a DependencyProperty as the backing store for ColorStart.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ColorLengthProperty =
        DependencyProperty.RegisterAttached("ColorLength", typeof(int), typeof(ColoredLettering), new FrameworkPropertyMetadata(0, OnColorLengthChanged));

    private static void OnColorLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock textBlock = d as TextBlock;
            if (textBlock != null)
            {
                if (e.NewValue == e.OldValue) return;
                if (e.NewValue is int)
                {
                    int start = GetColorStart(textBlock);
                    Brush brush = GetForeColor(textBlock);
                    if ((int)e.NewValue <= 0 || start <= 0 || brush == TextBlock.ForegroundProperty.DefaultMetadata.DefaultValue) return;
                    if (textBlock.TextEffects.Count != 0)
                    {
                        textBlock.TextEffects.Clear();
                    }
                    TextEffect textEffect = new TextEffect()
                    {
                        Foreground = brush,
                        PositionStart = start,
                        PositionCount = (int)e.NewValue
                    };
                    textBlock.TextEffects.Add(textEffect);
                }
            }
    }

    public static void SetForeColor(TextBlock textElement, Brush value)
    {
        textElement.SetValue(ColorStartProperty, value);
    }

    public static Brush GetForeColor(TextBlock textElement)
    {
        return (Brush)textElement.GetValue(ForeColorProperty);
    }

    // Using a DependencyProperty as the backing store for ForeColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ForeColorProperty =
        DependencyProperty.RegisterAttached("ForeColor", typeof(Brush), typeof(ColoredLettering), new PropertyMetadata(TextBlock.ForegroundProperty.DefaultMetadata.DefaultValue, OnForeColorChanged));

    private static void OnForeColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock textBlock = d as TextBlock;
        if (textBlock != null)
        {
            if (e.NewValue == e.OldValue) return;
            if (e.NewValue is Brush)
            {
                int start = GetColorStart(textBlock);
                int count = GetColorLength(textBlock);
                if (start <= 0 || count <= 0) return;
                if (textBlock.TextEffects.Count != 0)
                {
                    textBlock.TextEffects.Clear();
                }
                TextEffect textEffect = new TextEffect()
                {
                    Foreground = (Brush)e.NewValue,
                    PositionStart = start,
                    PositionCount = count
                };
                textBlock.TextEffects.Add(textEffect);
            }
        }
    }
}

调用时只需在TextBlock指定需要高亮内容的开始位置,内容长度以及高亮颜色即可。

<TextBlock local:ColoredLettering.ColorLength="{Binding Count}"
           local:ColoredLettering.ColorStart="{Binding Start}"
           local:ColoredLettering.ForeColor="{Binding ForeColor}"
           FontSize="20"
           Text="Hello World" />

总结

本文介绍的方法只是高亮第一个匹配到的关键字,如果需要高亮匹配到的所有内容,只需要对附加属性进行改造,以支持传入一组位置和颜色信息。
最后分享一个可以解析一组有限的HTML标记并显示它们的WPF控件HtmlTextBlock ,通过这个控件也可以实现查找结果中高亮关键字,甚至支持指定内容触发事件做一些逻辑操作。文章来源地址https://www.toymoban.com/news/detail-676860.html

到了这里,关于WPF使用TextBlock实现查找结果高亮显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • elasticsearch使用template搜索多个索引并且高亮返回结果

    由于搜索多个索引没办法以定义好的Entity来接收quey的结果,所以keyword搜索时不能按照以前的方式来直接分页搜索 所以这里选择重写搜索方法来自定义map返回结果,实现手动分页和替换高亮搜索的结果

    2024年02月11日
    浏览(41)
  • echarts 使用地图,设置背景图片和高亮图片,点击实现高亮显示,更换散点图图片,高亮散点图形,3D悬浮效果展示地图,集成Vue组件

    先看下   需要实现的效果: 第一步 需准备需要的插件  1  注意新版 echarts 的引入方式为:  import * as echarts from \\\'echarts\\\',这里我把 echarts 直接挂载到了Vue上,本项目使用echarts比较多,这样的话很方便,也可以在需要echarts的模块按需引入        在main.js中添加以下代码:

    2024年02月10日
    浏览(59)
  • Vue实现搜索关键词高亮显示

    最近写移动端项目的时候,遇到搜索高亮的需求,写篇文章纪录一下 先看效果:   以上为实现效果展示; 整体思路 : 对后台返回的数据进行操作,(我这里是模拟数据),使用正则去匹配搜索后,使用replace进行字符串的替换; 渲染数据部分使用v-html进行动态展示即可

    2024年02月15日
    浏览(51)
  • vue3项目使用pdf.js插件实现:搜索高亮、修改pdf.js显示的页码、向pdf.js传值、控制搜索、处理接口文件流

    官网地址:http://mozilla.github.io/pdf.js/ 中文文档地址:https://gitcode.gitcode.host/docs-cn/pdf.js-docs-cn/print.html PDF.js是基于HTML5技术构建的,用于展示可移植文档格式的文件(PDF),它可以在现代浏览器中使用且无需安装任何第三方插件。 pdf.js主要包含两个库文件 pdf.js:负责API解析 pdf.wor

    2024年02月13日
    浏览(70)
  • 【Elasticsearch】SpringBoot整合ES实现搜索功能 | 高亮显示

    先看代码: controller: serviceImpl: 小结 : 1、添加ES场景启动器 2、yaml配置ES 3、准备需要用到的变量 注:还有一个注入的RestHighLevelClient 结构如下: 具体调用的方法以及设置页码等参看代码。 加断点查看对应searchResponse数据结构: HighlightFields的数据结构: 对照kinaba结果: 3、根

    2024年02月11日
    浏览(46)
  • Elasticsearch查询结果高亮操作实战

    在进行搜索时,搜索出的内容中的会显示不同的颜色,称之为高亮 百度搜索\\\"狂飙\\\",如下所示: 或者在淘宝搜索“手机”,如下所示: 我们可以发现搜索的在搜索到的信息上都变成了红色高亮 通过开发者工具查看高亮数据的html代码实现: Elastic

    2024年02月12日
    浏览(73)
  • Selenium自动化实现高亮显示定位到的元素

    在调试Selenium脚本中,有时因为操作太快或操作不明显而不清楚是否定位到了正确的元素。我们可用通过执行js为定位到的元素添加样式,来高亮显示定位到的元素。 在Selenim Webdriver中,可以通过driver.exectue_scirpt() 执行JavaScript代码,执行的JavaScript代码是支持传入参数的,甚至

    2024年02月20日
    浏览(44)
  • Canvas、SVG实现鼠标滑过某个区域高亮显示的方案说明

    1、需求背景: 用户提供了某个厂区的底图(就一张静态图片),在底图中,划分了10个不规则区域,给了10个区域的高亮、开灯效果图片(切好了图),鼠标滑过每个区域的时候,要高亮显示,开灯的时候,显示开灯效果;看到这个需求的时候,挺懵的,有点不知从何下手,

    2024年02月16日
    浏览(39)
  • 通过RegExp实现 element UI tree 高亮显示(样式改变)搜索框过滤内容

            通过RegExp对象动态的实现字体样式的添加与删除。 element UI 中,树形控件进行过滤操作时,经常要求所搜字体进行一个高亮显示。         树形控件中提供了一个Attributes(属性) : filter-node-method  解释为: 对树节点进行筛选时执行的方法,返回 true 表示这个节

    2023年04月08日
    浏览(69)
  • 帝国CMS搜索结果显示数量的实现方法

    最近在做帝国CMS的搜索功能,记录一下方便大家以后使用,本文主要讲解一下修改帝国CMS搜索结果每页显示的数量的两种方法。 1、方法一:在后台搜索模板中直接设置数量 在后台——系统——系统参数设置——搜索设置——页面设置,如下图: 2、方法二:直接更改搜索系

    2024年02月03日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包