ハイパーリンクを含む可能性のあるテキストを RichTextBox にバインドして、テキストを通常のテキストとして表示し、リンクをハイパーリンクとして表示できるようにする必要があります。
たとえば、次のテキストがあります。
Join us on social networks
http://www.facebook.com/
テキスト内のリンクをハイパーリンクにしたいので、RichTextBox の結果は次のようになります。
ソーシャルネットワークに参加してください
ハイパーリンクを含む可能性のあるテキストを RichTextBox にバインドして、テキストを通常のテキストとして表示し、リンクをハイパーリンクとして表示できるようにする必要があります。
たとえば、次のテキストがあります。
Join us on social networks
http://www.facebook.com/
テキスト内のリンクをハイパーリンクにしたいので、RichTextBox の結果は次のようになります。
ソーシャルネットワークに参加してください
必要なものを実装しました
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Text.RegularExpressions;
using System.Windows.Media;
namespace NazarGrynko.UI.Controls
{
public class MyRichTextBox : RichTextBox
{
private const string UrlPattern = @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?";
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof (string), typeof(MyRichTextBox ), new PropertyMetadata(default(string), TextPropertyChanged));
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private static void TextPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var richTextBox = (MyRichTextBox)dependencyObject;
var text = (string) dependencyPropertyChangedEventArgs.NewValue;
int textPosition = 0;
var paragraph = new Paragraph();
var urlMatches = Regex.Matches(text, UrlPattern);
foreach (Match urlMatch in urlMatches)
{
int urlOccurrenceIndex = text.IndexOf(urlMatch.Value, textPosition, StringComparison.Ordinal);
if (urlOccurrenceIndex == 0)
{
var hyperlink = new Hyperlink
{
NavigateUri = new Uri(urlMatch.Value),
TargetName = "_blank",
Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
};
hyperlink.Inlines.Add(urlMatch.Value);
paragraph.Inlines.Add(hyperlink);
textPosition += urlMatch.Value.Length;
}
else
{
paragraph.Inlines.Add(text.Substring(textPosition, urlOccurrenceIndex - textPosition));
textPosition += urlOccurrenceIndex - textPosition;
var hyperlink = new Hyperlink
{
NavigateUri = new Uri(urlMatch.Value),
TargetName = "_blank",
Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
};
hyperlink.Inlines.Add(urlMatch.Value);
paragraph.Inlines.Add(hyperlink);
textPosition += urlMatch.Value.Length;
}
}
if (urlMatches.Count == 0)
{
paragraph.Inlines.Add(text);
}
richTextBox.Blocks.Add(paragraph);
}
}
}
使用例:
<MyRichTextBox Text="{Binding Message}"/>
ハイパーリンクを解析し、次の構造を作成します(もちろん、C#を使用)。
<RichTextBlock>
<Run>Hello World!</Run>
<Hyperlink NavigateUri="http://www.stackoverflow.com">http://www.stackoverflow.com</Hyperlink>
解決策をありがとう!
私が行った小さな変更の 1 つは、最後にありました。カウントのチェックを、全文の部分文字列を追加するだけの行に置き換えました。このようにして、最後の URL の後のすべてが切り捨てられず、すべてのテキストが保持されます。
paragraph.Inlines.Add(text.Substring(textPosition, text.Length - textPosition));
//if (urlMatches.Count == 0)
//{
// paragraph.Inlines.Add(text);
//}