《RichTextBox 》——— RichTextBox 数据绑定___代码添加

WP7 里面 richtextbox  不支持 HTML  也不支持 RTF  不支持 HTML 。 写 XAML 你会发现他有套自己的解析标准。。。。 悲催
同时 ricttextbox 也没啥 可以用来 绑定 内容 的属性 。。。。  这情况下 我们  的 ViewModel 中的类人要绑定打richtextbox 怎么办呢 ???


下面是我遭遇的实际问题 :
在做喂饭 (饭否客户端) 时 拿到 的微博内容 是一个字符串 里面 带有 @ #  还有url什的 。。  我想要展现这条微博 同时 @ # URL 要做成可点击的 link, 这是我考虑到使用 RICHTEXTBOX ,然后。。。 额。。。 就发生上述地问题。。。


刚开始思考这个问题时我第一想法是 重写 空间  在里面 做一个可以进行数据绑定的 动态属性  然后 在动态属性的Change 事件中 解析 动态属性的内容 在控件的blocks 添加要展现的内容 。。。

然后 就产生了下面 这样奇葩一样的控件

  1 using System;
  2 using System.Net;
  3 using System.Windows;
  4 using System.Windows.Controls;
  5 using System.Windows.Documents;
  6 using System.Windows.Ink;
  7 using System.Windows.Input;
  8 using System.Windows.Media;
  9 using System.Windows.Media.Animation;
 10 using System.Windows.Shapes;
 11 using System.Text.RegularExpressions;
 12 using System.ComponentModel;
 13 
 14 namespace WeiFan.UI.CustomeControl
 15 {
 16     public class FanFouContentBox :System.Windows.Controls.RichTextBox
 17     {
 18          /// <summary>
 19         /// 设置DependencyProperty属性
 20         /// </summary>
 21         public  DependencyProperty ContentProperty;
 22         /// <summary>
 23         /// 设置Content的访问器
 24         /// </summary>
 25         public string Content
 26         {
 27             set 
 28             {
 29                 SetValue(ContentProperty, value);
 30             }
 31             get
 32             {
 33                 return (string)GetValue(ContentProperty);
 34             }
 35         }
 36 
 37         public FanFouContentBox()
 38         {            
 39             //设置DependencyProperty的默认描述
 40             PropertyMetadata _metadata = new PropertyMetadata(string.Empty, OnContentChanged); ;
 41             ////设置默认值勤
 42             //_metadata.DefaultValue = null;
 43             ////设置是否影响布局
 44             //_metadata.AffectsMeasure = true;
 45             ////设置是否影响到其子控件
 46             //_metadata.Inherits = true;
 47             ////设置属性变化时的处理方法
 48             //_metadata.PropertyChangedCallback += OnImagePropertyChanged;
 49 
 50             ContentProperty = DependencyProperty.Register("Content", typeof(string), typeof(FanFouContentBox), _metadata);
 51             Content = this.Xaml;
 52         }
 53        
 54         /// <summary>
 55         /// 设置回调方法
 56         /// </summary>
 57         /// <param name="obj"></param>
 58         /// <param name="args"></param>
 59         void OnContentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
 60         {
 61             try
 62             {
 63                 Regex rootRegex = new Regex(@"(((http://)|(ftp://)|(https://)|(zune://)+)[^(\s)]{1,})|(#[^\s]{1,}#)|(((@{1})[^(\s|@)]{1,}))");//(@"(([http|ftp|https|zune]+://[^\s]*)|(#[^\s]*#)|)");
 64                 string target = args.NewValue as string;//@"http://t.cn/heMORnhttp://t.cn/heMORn 万能Url正则表达式[http,ftp,news,telnet.....]——史上最全Url正则表达式(基于RFC1738?) - 正则表达式 - 拼吾爱程序人生 http://t.cn/heMORn 1sfsdfsdfsdfsdfsdfsdfsdfdsfsdfsfsdfsdfsfsfsfsf1 Regex Tester – RegexPal http://regexpa 1sdfsfsdfsdfsdfs1";//string.Empty;
 65                 target = target.Replace("<b>", string.Empty);
 66                 target = target.Replace("</b>", string.Empty);
 67                 target = System.Net.HttpUtility.HtmlDecode(target);
 68                 Paragraph rootParagraph = new Paragraph();
 69 
 70                 MatchCollection mc = rootRegex.Matches(target);
 71                 if (mc.Count != 0)
 72                 {
 73                     int flag = 0;
 74                     for (int i = 0; i < mc.Count; i++)
 75                     {
 76                         if (mc[i].Index != 0)
 77                         {
 78                             Run r = new Run();
 79                             r.Foreground = this.Foreground;
 80                             r.Text = target.Substring(flag, mc[i].Index - flag);
 81 
 82                             flag = flag + r.Text.Length;
 83                             rootParagraph.Inlines.Add(r);
 84                         }
 85 
 86                         //Regex urlRegex = new Regex(@"[http|ftp|https|zune]+://[^\s]*");
 87                         //Regex trendRegex = new Regex(@"#[^\s]*#");
 88 
 89 
 90 
 91 
 92                         if (mc[i].Value.StartsWith("#"))
 93                         {
 94                             //热点
 95                             if (mc[i].Value.Length > 2)
 96                             {
 97                                 Hyperlink h = new Hyperlink();
 98                                 //h.TargetName = "_blank";
 99                                 System.Collections.Generic.Dictionary<string, string> param = new System.Collections.Generic.Dictionary<string, string>();
100 
101                                 string text = (mc[i].Value).Remove(0, 1);
102                                 text = text.Remove(text.Length - 1, 1);
103                                 param.Add("query", text);
104 
105                                 h.NavigateUri = new Uri("/SearchResult.xaml?" + WeiFan.Utility.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative);
106 
107                                 Run r = new Run();
108                                 r.Text = mc[i].Value;
109                                 h.Inlines.Add(r);
110                                 rootParagraph.Inlines.Add(h);
111                                 flag = flag + mc[i].Length;
112                             }
113                         }
114                         else if (mc[i].Value.StartsWith("@"))
115                         {
116                             System.Collections.Generic.Dictionary<string, string> param = new System.Collections.Generic.Dictionary<string, string>();
117                             param.Add("content", mc[i].Value);
118                             //PhoneApplicationFrame.Navigate(new Uri("/PublishStatus.xaml?" + WeiFan.Utiltiy.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative));
119 
120                             Hyperlink h = new Hyperlink();
121                             
122                             h.NavigateUri = new Uri("/PublishStatus.xaml?" + WeiFan.Utility.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative);
123 
124                             Run r = new Run();
125                             r.Text = mc[i].Value;
126                             h.Inlines.Add(r);
127                             rootParagraph.Inlines.Add(h);
128                             flag = flag + mc[i].Length;
129                         }
130 
131                         else
132                         {
133                             //URL
134                             Hyperlink h = new Hyperlink();
135                             h.TargetName = "_blank";
136                             h.NavigateUri = new Uri(mc[i].Value);
137                             Run r = new Run();
138                             r.Text = mc[i].Value;
139                             h.Inlines.Add(r);
140                             rootParagraph.Inlines.Add(h);
141                             flag = flag + mc[i].Length;
142                         }
143 
144 
145 
146                     }
147                     if (flag < target.Length - 1)
148                     {
149                         Run r = new Run();
150                         r.Text = target.Substring(flag, target.Length - flag);
151                         flag = flag + r.Text.Length;
152                         rootParagraph.Inlines.Add(r);
153                     }
154                 }
155                 else
156                 {
157                     rootParagraph.Inlines.Add((new Run()).Text = target);
158                 }
159                 this.Blocks.Clear();
160                 this.Blocks.Add(rootParagraph);
161             }
162             catch (Exception e)
163             {
164                 System.Diagnostics.Debug.WriteLine("Exception in Custom.RichTextBox.OnContentChanged:" + e.Message);
165             }
166         }
167 
168       
169     }
170 }

不过 这方法 有个 非常蛋疼的缺陷就是 。。。   我这里涉及到解析多种文本 那就蛋疼 了 。。。  每种 挨个重写一次 。。。
后来 看到了 behavior 这种好东西 。。。  意识到 可以通过 behavior 吧 解析 和 动态属性给剥离出来

直接上代码

  1 using System;
  2 using System.Net;
  3 using System.Text.RegularExpressions;
  4 using System.Windows;
  5 using System.Windows.Controls;
  6 using System.Windows.Documents;
  7 using System.Windows.Ink;
  8 using System.Windows.Input;
  9 using System.Windows.Media;
 10 using System.Windows.Media.Animation;
 11 using System.Windows.Shapes;
 12 using System.Windows.Interactivity;
 13 
 14 namespace WeiFan.UI.Behavior
 15 {
 16     public class ConvertFanFouContentBehavior :Behavior<RichTextBox>
 17     {
 18         public static DependencyProperty ContentProperty
 19             = DependencyProperty.RegisterAttached(
 20                 "Content", typeof(string),
 21                 typeof(RichTextBox),
 22                 new PropertyMetadata(null, OnContentChanged));
 23 
 24         public string Content
 25         {
 26             set
 27             {
 28                 SetValue(ContentProperty, value);
 29             }
 30             get
 31             {
 32                 return (string)GetValue(ContentProperty);
 33             }
 34         }
 35 
 36         public bool IsEnable { get; set; }
 37 
 38         public ConvertFanFouContentBehavior()
 39         {
 40             IsEnable = true;
 41             
 42         }
 43 
 44         private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
 45         {
 46             string content = e.NewValue as string;
 47 
 48             ConvertFanFouContentBehavior sender = d as ConvertFanFouContentBehavior;
 49 
 50             if (!string.IsNullOrWhiteSpace(content) && d!=null)
 51             {
 52                 sender.ConvertFanfouContent(content);
 53             }
 54         }
 55 
 56         void ConvertFanfouContent(string content)
 57         {
 58             try
 59             {
 60                 Regex rootRegex = new Regex(@"(((http://)|(ftp://)|(https://)|(zune://)+)[^(\s)]{1,})|(#[^\s]{1,}#)|(((@{1})[^(\s|@)]{1,}))");//(@"(([http|ftp|https|zune]+://[^\s]*)|(#[^\s]*#)|)");
 61                 string target = content as string;//@"http://t.cn/heMORnhttp://t.cn/heMORn 万能Url正则表达式[http,ftp,news,telnet.....]——史上最全Url正则表达式(基于RFC1738?) - 正则表达式 - 拼吾爱程序人生 http://t.cn/heMORn 1sfsdfsdfsdfsdfsdfsdfsdfdsfsdfsfsdfsdfsfsfsfsf1 Regex Tester – RegexPal http://regexpa 1sdfsfsdfsdfsdfs1";//string.Empty;
 62                 target = target.Replace("<b>", string.Empty);
 63                 target = target.Replace("</b>", string.Empty);
 64                 target = System.Net.HttpUtility.HtmlDecode(target);
 65                 Paragraph rootParagraph = new Paragraph();
 66 
 67                 MatchCollection mc = rootRegex.Matches(target);
 68                 if (mc.Count != 0)
 69                 {
 70                     int flag = 0;
 71                     for (int i = 0; i < mc.Count; i++)
 72                     {
 73                         if (mc[i].Index != 0)
 74                         {
 75                             Run r = new Run();
 76                             r.Foreground = this.AssociatedObject.Foreground;
 77                             r.Text = target.Substring(flag, mc[i].Index - flag);
 78 
 79                             flag = flag + r.Text.Length;
 80                             rootParagraph.Inlines.Add(r);
 81                         }
 82 
 83                         //Regex urlRegex = new Regex(@"[http|ftp|https|zune]+://[^\s]*");
 84                         //Regex trendRegex = new Regex(@"#[^\s]*#");
 85 
 86 
 87 
 88 
 89                         if (mc[i].Value.StartsWith("#"))
 90                         {
 91                             //热点
 92                             if (mc[i].Value.Length > 2)
 93                             {
 94                                 Hyperlink h = new Hyperlink();
 95                                 //h.TargetName = "_blank";
 96                                 System.Collections.Generic.Dictionary<string, string> param = new System.Collections.Generic.Dictionary<string, string>();
 97 
 98                                 string text = (mc[i].Value).Remove(0, 1);
 99                                 text = text.Remove(text.Length - 1, 1);
100                                 param.Add("query", text);
101 
102                                 h.NavigateUri = new Uri("/SearchResult.xaml?" + WeiFan.Utility.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative);
103 
104                                 Run r = new Run();
105                                 r.Text = mc[i].Value;
106                                 h.Inlines.Add(r);
107                                 rootParagraph.Inlines.Add(h);
108                                 flag = flag + mc[i].Length;
109                             }
110                         }
111                         else if (mc[i].Value.StartsWith("@"))
112                         {
113                             System.Collections.Generic.Dictionary<string, string> param = new System.Collections.Generic.Dictionary<string, string>();
114                             param.Add("content", mc[i].Value);
115                             //PhoneApplicationFrame.Navigate(new Uri("/PublishStatus.xaml?" + WeiFan.Utiltiy.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative));
116 
117                             Hyperlink h = new Hyperlink();
118 
119                             h.NavigateUri = new Uri("/PublishStatus.xaml?" + WeiFan.Utility.HttpUtility.URLQueryStringBuilder(param), UriKind.Relative);
120 
121                             Run r = new Run();
122                             r.Text = mc[i].Value;
123                             h.Inlines.Add(r);
124                             rootParagraph.Inlines.Add(h);
125                             flag = flag + mc[i].Length;
126                         }
127 
128                         else
129                         {
130                             //URL
131                             Hyperlink h = new Hyperlink();
132                             h.TargetName = "_blank";
133                             h.NavigateUri = new Uri(mc[i].Value);
134                             Run r = new Run();
135                             r.Text = mc[i].Value;
136                             h.Inlines.Add(r);
137                             rootParagraph.Inlines.Add(h);
138                             flag = flag + mc[i].Length;
139                         }
140 
141 
142 
143                     }
144                     if (flag < target.Length - 1)
145                     {
146                         Run r = new Run();
147                         r.Text = target.Substring(flag, target.Length - flag);
148                         flag = flag + r.Text.Length;
149                         rootParagraph.Inlines.Add(r);
150                     }
151                 }
152                 else
153                 {
154                     rootParagraph.Inlines.Add((new Run()).Text = target);
155                 }
156                 this.AssociatedObject.Blocks.Clear();
157                 this.AssociatedObject.Blocks.Add(rootParagraph);
158             }
159             catch (Exception e)
160             {
161                 System.Diagnostics.Debug.WriteLine("Exception in Custom.RichTextBox.OnContentChanged:" + e.Message);
162             }
163         }
164 
165     }
166 }

然后嘛。。。

在 XMAL 里面使用 这个 behavior

1 <RichTextBox  x:Name="rtb_content" FontSize="24"  Width="365"  TextWrapping="Wrap" >
2                                 <i:Interaction.Behaviors>
3                                     <Behavior:ConvertFanFouContentBehavior Content="{Binding Path=Content}"></Behavior:ConvertFanFouContentBehavior>
4                                 </i:Interaction.Behaviors>
5                             </RichTextBox>

然后 ,。。。 就没有 然后了

转自:http://www.wpdevn.com/showtopic-32.aspx

posted @ 2012-06-14 11:52  ╰→劉じ尛鶴  阅读(1153)  评论(0编辑  收藏  举报