SilverLight高亮顯示文本

    文筆很差,就長話短說,就是想實現這樣的效果,好比在成都二環路南一段一號附一號鳳舞九天網吧 ,搜索 二環路 九天網吧 而後結果中高亮顯示。算法

   

         <local:TextBlockHighLight TextSource="成都二環路南一段一號附一號鳳舞九天網吧" SearchText="二環路 九天網吧 "  FontSize="12" FontFamily="Comic Sans MS"  Margin="10"/>

 

  代碼以下:app

    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() ,可是在最早實現中,因爲本生本身正則不是好好,因此但願你們提出更好的算法。測試

相關文章
相關標籤/搜索