LongListSelector中的RichTextBox:如何拦截点击HyperLink?

时间:2014-09-23 15:05:32

标签: c# xaml windows-phone-8 richtextbox longlistselector

我有应用程序 - 聊天。对于查看使用过的LongListSelector的消息。每条消息都可以包含BB标签:B,U,I,URL,IMG,COLOR。它使用扩展的RichTextBox正确处理:

using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows.Media;
using System.Text.RegularExpressions;

namespace System.Windows.Controls
{
    public class RichTextViewer : RichTextBox
    {
        public const string RichTextPropertyName = "RichText";

        public static readonly DependencyProperty RichTextProperty =
            DependencyProperty.Register(RichTextPropertyName,
                                        typeof(string),
                                        typeof(RichTextBox),
                                        new PropertyMetadata(
                                            new PropertyChangedCallback
                                                (RichTextPropertyChanged)));

        public RichTextViewer()
        {
            IsReadOnly = true;
            Background = new SolidColorBrush { Opacity = 0 };
            BorderThickness = new Thickness(0);
        }

        public string RichText
        {
            get { return (string)GetValue(RichTextProperty); }
            set { SetValue(RichTextProperty, value); }
        }

        private static void RichTextPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            string xaml = "<Paragraph xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" + ((string)dependencyPropertyChangedEventArgs.NewValue) + "</Paragraph>";
            xaml=xaml.Replace("\r", "");
            xaml = xaml.Replace("\n", "<LineBreak/>");
            xaml = Regex.Replace(xaml, "\\[b\\](.+?)\\[/b\\]", "<Bold>$1</Bold>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[i\\](.+?)\\[/i\\]", "<Italic>$1</Italic>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[u\\](.+?)\\[/u\\]", "<Underline>$1</Underline>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[color=(.+?)\\](.+?)\\[/color\\]", "<Span Foreground=\"$1\">$2</Span>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[img\\](.+?)\\[/img\\]", "<InlineUIContainer><Image Source=\"$1\" Stretch=\"None\" /></InlineUIContainer>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[img=(.+?)\\]", "<InlineUIContainer><Image Source=\"$1\" Stretch=\"None\" /></InlineUIContainer>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[url\\](.+?)\\[/url\\]", "<Hyperlink NavigateUri=\"$1\">$1</Hyperlink>", RegexOptions.IgnoreCase);
            xaml = Regex.Replace(xaml, "\\[url=(.+?)\\](.+?)\\[/url\\]", "<Hyperlink NavigateUri=\"$1\">$2</Hyperlink>", RegexOptions.IgnoreCase);
            ((RichTextBox)dependencyObject).Blocks.Clear();
            ((RichTextBox)dependencyObject).Blocks.Add(XamlReader.Load(xaml) as Paragraph);
        }
    }
}

XAML:

<Controls:RichTextViewer RichText="{Binding Message}" Width="350" />

它运行良好,但我需要拦截HyperLink标签上的点击并使用我的应用程序处理它或在浏览器中打开(取决于URL)。我无法理解如何制作它。我认为有三种方法可以实现它:

  1. 将Click =“HyperlinkBut​​ton_Click”添加到每个HyperLink标记。它不起作用,我得到例外:

    XamlReader.Load()不接受事件处理程序。不允许设置事件'System.Windows.Documents.Hyperlink.Click'。

  2. 尝试在XamlReader.Load()之后以编程方式将事件处理程序添加到每个HyperLink。这意味着内存中的每个链接(聊天可以包含许多消息,一条消息可以包含很少的链接)的许多处理程序,我不确定这是好方法。

  3. 为我的应用程序注册自定义URI方案,并强制所有指向此方案的链接。

  4. 在这种情况下,有什么方法可以做得更好?

0 个答案:

没有答案