SilverLight高亮显示文本

    文笔不好,就长话短说,就是想实现这样的效果,比如在成都二环路南一段一号附一号凤舞九天网吧 ,搜索 二环路 九天网吧 然后结果中高亮显示。

   

         <local:TextBlockHighLight TextSource="成都二环路南一段一号附一号凤舞九天网吧" SearchText="二环路 九天网吧 "  FontSize="12" FontFamily="Comic Sans MS"  Margin="10"/>

 

  代码如下:

    public partial class TextBlockHighLight : UserControl

    {

        public TextBlockHighLight()

        {

            InitializeComponent();

            this.LayoutRoot.Children.Add(_txtBlock);

        }

        public string TextSource

        {

            get { return (string)GetValue(TextSourceProperty); }

            set { SetValue(TextSourceProperty, value); }

        }

        private TextBlock _txtBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap };

        // Using a DependencyProperty as the backing store for TextSource.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty TextSourceProperty =

            DependencyProperty.Register("TextSource", typeof(string), typeof(TextBlockHighLight), new PropertyMetadata(string.Empty, (o, e) =>

            {

                var _this = o as TextBlockHighLight;

                if (string.IsNullOrWhiteSpace(e.NewValue.ToString()))

                {

                    _this._txtBlock.Text = string.Empty;

                }

                else

                {

                    _this._txtBlock.Text = e.NewValue.ToString();

                }

            }));



        public string SearchText

        {

            get { return (string)GetValue(SearchTextProperty); }

            set { SetValue(SearchTextProperty, value); }

        }



        // Using a DependencyProperty as the backing store for SearchText.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty SearchTextProperty =

            DependencyProperty.Register("SearchText", typeof(string), typeof(TextBlockHighLight), new PropertyMetadata(string.Empty, (o, e) =>

            {

                var _this = o as TextBlockHighLight;

                ///如果字符都不为空

                if ((!string.IsNullOrWhiteSpace(e.NewValue.ToString()))

                    && (!string.IsNullOrWhiteSpace(_this._txtBlock.Text)))

                {

                    System.Text.StringBuilder sb = new System.Text.StringBuilder();



                    sb.Append("<TextBlock  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">");

                    sb.Append(" <TextBlock.Inlines>");

                    sb.Append("<Run>");



                    var strs = e.NewValue.ToString().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                    if (strs.Length > 1)

                    {

                        ///移除相同的 比如二环路 二环 那么会移除二环

                        for (int i = 0; i < strs.Length; i++)

                        {

                            for (int j = i + 1; j < strs.Length; j++)

                            {

                                if (strs[j].Contains(strs[i]))

                                {

                                    ///无效的就设为空字符串

                                    strs[i] = string.Empty;

                                    break;

                                }

                            }

                        }

                    }



                    ///去除空字符串

                    strs = strs.Where(c => !string.IsNullOrEmpty(c)).ToArray();



                    var tmpSB = new System.Text.StringBuilder();



                    foreach (var item in strs)

                    {

                        if (tmpSB.Length == 0)

                        {

                            ///设置要高亮显示的样式 ,这里是测试就写死了

                            tmpSB.Append(_this.TextSource.Replace(item, "</Run><Run Text=\"" + item + "\"  Foreground=\"Red\" FontWeight=\"Bold\"></Run> <Run>"));

                        }

                        else

                        {

                            tmpSB.Replace(item, "</Run><Run Text=\"" + item + "\"  Foreground=\"Red\" FontWeight=\"Bold\"></Run> <Run>");

                        }

                    }

                    sb.Append(tmpSB.ToString());

                    sb.Append("</Run>");

                    sb.Append("</TextBlock.Inlines>");

                    sb.Append("</TextBlock>");



                    var txt = System.Windows.Markup.XamlReader.Load(sb.ToString()) as TextBlock;



                    List<Inline> inlines = new List<Inline>();

                    txt.Inlines.ToList().ForEach(c => inlines.Add(c));



                    txt.Inlines.Clear();

                    _this._txtBlock.Text = null;

                    foreach (var item in inlines)

                    {

                        _this._txtBlock.Inlines.Add(item);

                    }

                    _this.UpdateLayout();

                }

                else

                {

                    _this._txtBlock.Inlines.Clear();

                    _this._txtBlock.Text = _this.TextSource;

                }

            }));

    }

 有些BUG,如果先更新要搜索的字符串,再更新源字符串不会触发事件,但是在实际使用中也是在源字符串里面找要搜索的字符串。搜索字符串里面是加空格分隔的。应该有更好的算法,也可以用正则匹配就用像我代码里面用 XamlReader.Load() ,但是在最先实现中,由于本生自己正则不是好好,所以希望大家提出更好的算法。

你可能感兴趣的:(silverlight)