我有应用程序 - 聊天。对于查看使用过的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)。我无法理解如何制作它。我认为有三种方法可以实现它:
将Click =“HyperlinkButton_Click”添加到每个HyperLink标记。它不起作用,我得到例外:
XamlReader.Load()不接受事件处理程序。不允许设置事件'System.Windows.Documents.Hyperlink.Click'。
尝试在XamlReader.Load()之后以编程方式将事件处理程序添加到每个HyperLink。这意味着内存中的每个链接(聊天可以包含许多消息,一条消息可以包含很少的链接)的许多处理程序,我不确定这是好方法。
为我的应用程序注册自定义URI方案,并强制所有指向此方案的链接。
在这种情况下,有什么方法可以做得更好?