通过绑定在 TextBlock 中创建超链接
Create Hyperlink in TextBlock via Binding
我的问题是从文本内容中找到 url 并通过数据绑定将其转换为可点击的超链接。
这是我试过的
<TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap"
Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16"
TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
<Run Text="{Binding description, Converter={StaticResource statusFormatter}}" />
</TextBlock>
在代码中,
public class StatusFormatter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return returnTextWithUrl((String)value);
}
public static String returnTextWithUrl(String text)
{
if(text == null) { return null; }
MatchCollection mactches = uriFindRegex.Matches(text);
foreach (Match match in mactches)
{
//Need Help here
HyperlinkButton hyperlink = new HyperlinkButton();
hyperlink.Content = match.Value;
hyperlink.NavigateUri = new Uri(match.Value);
text = text.Replace(match.Value, ??);
}
return text;
}
}
}
输出应该是这样的
<TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap"
Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16"
TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
Click this link -
<Hyperlink NavigateUri="http://www.bing.com">bing</Hyperlink>
- for more info.
</TextBlock>
有帮助吗?
不能将超链接对象放入字符串中。相反,您需要 return 一个包含来自转换器的内联的 Span。纯文本将是 运行 个对象,链接将是超链接对象。
public static Span returnTextWithUrl(String text)
{
if(text == null) { return null; }
var span = new Span();
MatchCollection mactches = uriFindRegex.Matches(text);
int lastIndex = 0;
foreach (Match match in mactches)
{
var run = new Run(text.Substring(lastIndex, match.Index - lastIndex));
span.Inlines.Add(run);
lastIndex = match.Index + match.Length;
var hyperlink = new Hyperlink();
hyperlink.Content = match.Value;
hyperlink.NavigateUri = new Uri(match.Value);
span.Inlines.Add(hyperlink);
}
span.Inlines.Add(new Run(text.Substring(lastIndex)));
return span;
}
要执行您想要的操作,您必须使用 TextBlock 的 Inlines 属性,但因为它不是DependencyProperty,不能作为绑定目标。我们将不得不扩展您的 TextBlock class,但由于它是 密封的,我们将不得不使用其他 class。
让我们定义 static class,这将添加适当的 Inline - Hyperlink or Run,具体取决于 Regex 匹配。它可以看起来像这样的例子:
public static class TextBlockExtension
{
public static string GetFormattedText(DependencyObject obj)
{ return (string)obj.GetValue(FormattedTextProperty); }
public static void SetFormattedText(DependencyObject obj, string value)
{ obj.SetValue(FormattedTextProperty, value); }
public static readonly DependencyProperty FormattedTextProperty =
DependencyProperty.Register("FormattedText", typeof(string), typeof(TextBlockExtension),
new PropertyMetadata(string.Empty, (sender, e) =>
{
string text = e.NewValue as string;
var textBl = sender as TextBlock;
if (textBl != null)
{
textBl.Inlines.Clear();
Regex regx = new Regex(@"(http://[^\s]+)", RegexOptions.IgnoreCase);
var str = regx.Split(text);
for (int i = 0; i < str.Length; i++)
if (i % 2 == 0)
textBl.Inlines.Add(new Run { Text = str[i] });
else
{
Hyperlink link = new Hyperlink { NavigateUri = new Uri(str[i]), Foreground = Application.Current.Resources["PhoneAccentBrush"] as SolidColorBrush };
link.Inlines.Add(new Run { Text = str[i] });
textBl.Inlines.Add(link);
}
}
}));
}
那么在XAML中我们就这样使用:
<TextBlock local:TextBlockExtension.FormattedText="{Binding MyText}" FontSize="15"/>
在我的 属性 中输入一些文字后:
private void firstBtn_Click(object sender, RoutedEventArgs e)
{
MyText = @"Simple text with http://mywebsite.com link";
}
我能看到这样的结果:
我在寻找 UWP
的相同内容时偶然发现了这个 post。如果您也在这里,我建议您使用 HyperlinkButton
而不是包裹在 Textblock
中的 Hyperlink
。以下是有关如何使用它的代码。
<HyperlinkButton Content="{x:Bind Text}" NavigateUri="{x:Bind Hyperlink}"/>
您也可以使用 Binding
而不是 x:Bind
是的,您也可以设置 Mode=OneWay
。
我的问题是从文本内容中找到 url 并通过数据绑定将其转换为可点击的超链接。
这是我试过的
<TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap"
Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16"
TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
<Run Text="{Binding description, Converter={StaticResource statusFormatter}}" />
</TextBlock>
在代码中,
public class StatusFormatter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return returnTextWithUrl((String)value);
}
public static String returnTextWithUrl(String text)
{
if(text == null) { return null; }
MatchCollection mactches = uriFindRegex.Matches(text);
foreach (Match match in mactches)
{
//Need Help here
HyperlinkButton hyperlink = new HyperlinkButton();
hyperlink.Content = match.Value;
hyperlink.NavigateUri = new Uri(match.Value);
text = text.Replace(match.Value, ??);
}
return text;
}
}
}
输出应该是这样的
<TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap"
Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16"
TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
Click this link -
<Hyperlink NavigateUri="http://www.bing.com">bing</Hyperlink>
- for more info.
</TextBlock>
有帮助吗?
不能将超链接对象放入字符串中。相反,您需要 return 一个包含来自转换器的内联的 Span。纯文本将是 运行 个对象,链接将是超链接对象。
public static Span returnTextWithUrl(String text)
{
if(text == null) { return null; }
var span = new Span();
MatchCollection mactches = uriFindRegex.Matches(text);
int lastIndex = 0;
foreach (Match match in mactches)
{
var run = new Run(text.Substring(lastIndex, match.Index - lastIndex));
span.Inlines.Add(run);
lastIndex = match.Index + match.Length;
var hyperlink = new Hyperlink();
hyperlink.Content = match.Value;
hyperlink.NavigateUri = new Uri(match.Value);
span.Inlines.Add(hyperlink);
}
span.Inlines.Add(new Run(text.Substring(lastIndex)));
return span;
}
要执行您想要的操作,您必须使用 TextBlock 的 Inlines 属性,但因为它不是DependencyProperty,不能作为绑定目标。我们将不得不扩展您的 TextBlock class,但由于它是 密封的,我们将不得不使用其他 class。
让我们定义 static class,这将添加适当的 Inline - Hyperlink or Run,具体取决于 Regex 匹配。它可以看起来像这样的例子:
public static class TextBlockExtension
{
public static string GetFormattedText(DependencyObject obj)
{ return (string)obj.GetValue(FormattedTextProperty); }
public static void SetFormattedText(DependencyObject obj, string value)
{ obj.SetValue(FormattedTextProperty, value); }
public static readonly DependencyProperty FormattedTextProperty =
DependencyProperty.Register("FormattedText", typeof(string), typeof(TextBlockExtension),
new PropertyMetadata(string.Empty, (sender, e) =>
{
string text = e.NewValue as string;
var textBl = sender as TextBlock;
if (textBl != null)
{
textBl.Inlines.Clear();
Regex regx = new Regex(@"(http://[^\s]+)", RegexOptions.IgnoreCase);
var str = regx.Split(text);
for (int i = 0; i < str.Length; i++)
if (i % 2 == 0)
textBl.Inlines.Add(new Run { Text = str[i] });
else
{
Hyperlink link = new Hyperlink { NavigateUri = new Uri(str[i]), Foreground = Application.Current.Resources["PhoneAccentBrush"] as SolidColorBrush };
link.Inlines.Add(new Run { Text = str[i] });
textBl.Inlines.Add(link);
}
}
}));
}
那么在XAML中我们就这样使用:
<TextBlock local:TextBlockExtension.FormattedText="{Binding MyText}" FontSize="15"/>
在我的 属性 中输入一些文字后:
private void firstBtn_Click(object sender, RoutedEventArgs e)
{
MyText = @"Simple text with http://mywebsite.com link";
}
我能看到这样的结果:
我在寻找 UWP
的相同内容时偶然发现了这个 post。如果您也在这里,我建议您使用 HyperlinkButton
而不是包裹在 Textblock
中的 Hyperlink
。以下是有关如何使用它的代码。
<HyperlinkButton Content="{x:Bind Text}" NavigateUri="{x:Bind Hyperlink}"/>
您也可以使用 Binding
而不是 x:Bind
是的,您也可以设置 Mode=OneWay
。