WP7 RichTextBox 蛋疼的 数据绑定
2012-01-18 17:05 F-sea 阅读(1896) 评论(1) 编辑 收藏 举报WP7 里面 richtextbox 不支持 HTML 也不支持 RTF 不支持 HTML 。 写 XAML 你会发现他有套自己的解析标准。。。。 悲催
同时 ricttextbox 也没啥 可以用来 绑定 内容 的属性 。。。。 这情况下 我们 的 ViewModel 中的类人要绑定打richtextbox 怎么办呢 ???
下面是我遭遇的实际问题 :
在做喂饭 (饭否客户端) 时 拿到 的微博内容 是一个字符串 里面 带有 @ # 还有url什的 。。 我想要展现这条微博 同时 @ # URL 要做成可点击的 link, 这是我考虑到使用 RICHTEXTBOX ,然后。。。 额。。。 就发生上述地问题。。。
刚开始思考这个问题时我第一想法是 重写 空间 在里面 做一个可以进行数据绑定 动态属性 然后 在动态属性的Change 件中 解析动态属性的内容并在控件的blocks 添加要展现的内容 。。。
然后 就产生了下面 这样奇葩一样的控件
public class FanFouContentBox :System.Windows.Controls.RichTextBox
{
/// <summary>
/// 设置DependencyProperty属性
/// </summary>
public DependencyProperty ContentProperty;
/// <summary>
/// 设置Content的访问器
/// </summary>
public string Content
{
set
{
SetValue(ContentProperty, value);
}
get
{
return (string)GetValue(ContentProperty);
}
}
public FanFouContentBox()
{
//设置DependencyProperty的默认描述
PropertyMetadata _metadata = new PropertyMetadata(string.Empty, OnContentChanged); ;
ContentProperty = DependencyProperty.Register("Content", typeof(string), typeof(FanFouContentBox), _metadata);
Content = this.Xaml;
}
/// <summary>
/// 设置回调方法
/// </summary>
/// <param name="obj"></param>
/// <param name="args"></param>
void OnContentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
// 用正则解析数据 并添加类人
try
{
Regex rootRegex = new Regex(@"(((http://)|(ftp://)|(https://)|(zune://)+)[^(\s)]{1,})|(#[^\s]{1,}#)|(((@{1})[^(\s|@)]{1,}))");//(@"(([http|ftp|https|zune]+://[^\s]*)|(#[^\s]*#)|)");
string target = args.NewValue as string;
target = target.Replace("<b>", string.Empty);
target = target.Replace("</b>", string.Empty);
target = System.Net.HttpUtility.HtmlDecode(target);
Paragraph rootParagraph = new Paragraph();
MatchCollection mc = rootRegex.Matches(target);
///
解析数据 并向rootParagraph 中添加内容
。。。。。 解析代码太长先省略了
///
this.Blocks.Clear();
this.Blocks.Add(rootParagraph);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Exception in Custom.RichTextBox.OnContentChanged:" + e.Message);
}
}
}
}
不过 这方法 有个 非常蛋疼的缺陷就是 。。。 我这里涉及到解析多种文本 那就蛋疼 了 。。。 每种 挨个重写一次 。。。
后来 看到了 behavior 这种好东西 。。。 意识到 可以通过 behavior 吧 解析 和 动态属性给剥离出来
public class ConvertFanFouContentBehavior :Behavior<RichTextBox>
{
//动态属性
public static DependencyProperty ContentProperty
= DependencyProperty.RegisterAttached(
"Content", typeof(string),
typeof(RichTextBox),
new PropertyMetadata(null, OnContentChanged));
public string Content
{
set
{
SetValue(ContentProperty, value);
}
get
{
return (string)GetValue(ContentProperty);
}
}
public bool IsEnable { get; set; }
public ConvertFanFouContentBehavior()
{
IsEnable = true;
}
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
string content = e.NewValue as string;
ConvertFanFouContentBehavior sender = d as ConvertFanFouContentBehavior;
if (!string.IsNullOrWhiteSpace(content) && d!=null)
{
sender.ConvertFanfouContent(content);
}
}
void ConvertFanfouContent(string content)
{
try
{
Regex rootRegex = new Regex(@"(((http://)|(ftp://)|(https://)|(zune://)+)[^(\s)]{1,})|(#[^\s]{1,}#)|(((@{1})[^(\s|@)]{1,}))");//(@"(([http|ftp|https|zune]+://[^\s]*)|(#[^\s]*#)|)");
string target = content as string;
target = target.Replace("<b>", string.Empty);
target = target.Replace("</b>", string.Empty);
target = System.Net.HttpUtility.HtmlDecode(target);
Paragraph rootParagraph = new Paragraph();
MatchCollection mc = rootRegex.Matches(target);
///
解析数据 并向rootParagraph 中添加内容
。。。。。 解析代码太长先省略了
///
this.AssociatedObject.Blocks.Clear();
this.AssociatedObject.Blocks.Add(rootParagraph);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Exception in Custom.RichTextBox.OnContentChanged:" + e.Message);
}
}
}
然后嘛。。。
在 XMAL 里的RichTextBox 中 使用 该 behavior 同时在 behavior 的 content属性中绑定我需要绑定的 内容
<RichTextBox x:Name="rtb_content" FontSize="24" Width="365" TextWrapping="Wrap" >
<i:Interaction.Behaviors>
<Behavior:ConvertFanFouContentBehavior Content="{Binding Path=Content}"></Behavior:ConvertFanFouContentBehavior>
</i:Interaction.Behaviors>
</RichTextBox>
然后 ,。。。 就没有 然后了
对了 记得 现在 xmal 中间添加 namesapce
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
不然他不知道 那个i 是个什么东西
这样做的 我们就只需要 根据要解析的文本类型 来做对应的behavior 就 OK 了 。。。 不用 挨个 重写空间 。。。 如果 有比较 可以 做一个 behavior 基类 然后 每种 解析方式 只需要 继承 并重写 对应 解析方法 就 OK 这个我就 不上具体 的方法了 。。。
BTW : 本文同步发表于: http://www.wpdevn.com/showtopic-32.aspx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步