我有一个自定义 TextBlock 可以检测文本中的链接并使它们可点击。需要添加在 TextBlock 中选择任意文本以将其进一步复制到内存缓冲区的功能。任何想法如何做到这一点?
超链接文本块类:
public class HyperlinkTextBlock : TextBlock
{
private static readonly Regex HyperlinkRegex = new Regex(@"(https?|ftp):\/\/[^\s/$.?#].[^\s,]*");
public static readonly DependencyProperty HyperlinkStyleProperty = DependencyProperty.Register("HyperlinkStyle",
typeof(Style), typeof(HyperlinkTextBlock));
static HyperlinkTextBlock()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HyperlinkTextBlock),
new FrameworkPropertyMetadata(typeof(HyperlinkTextBlock)));
}
public HyperlinkTextBlock()
{
TargetUpdated += (s, args) =>
Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(ParseHyperlinks));
}
public event EventHandler<HyperlinkPressedEventArgs> HyperlinkPressed;
public Style HyperlinkStyle
{
private get => (Style) GetValue(HyperlinkStyleProperty);
set => SetValue(HyperlinkStyleProperty, value);
}
private void ParseHyperlinks()
{
var text = Text;
var matches = HyperlinkRegex.Matches(text);
if (matches.Count == 0)
return;
Inlines.Clear();
var lastIndex = 0;
foreach (Match match in matches)
{
Inlines.Add(text.Substring(lastIndex, match.Index - lastIndex));
lastIndex = match.Index + match.Length;
var run = new Run(match.Value) {Style = HyperlinkStyle};
run.MouseDown += RunOnMouseDown;
Inlines.Add(run);
}
Inlines.Add(text.Substring(lastIndex));
}
private void RunOnMouseDown(object sender, MouseButtonEventArgs args)
{
if (!(sender is Run run)) return;
var handler = HyperlinkPressed;
handler?.Invoke(this, new HyperlinkPressedEventArgs(run.Text));
}
}
public class HyperlinkPressedEventArgs : EventArgs
{
public readonly Uri Hyperlink;
public HyperlinkPressedEventArgs(string hyperlink)
{
Hyperlink = new Uri(hyperlink);
}
}
用法:
<Style x:Key="HyperlinkStyle" TargetType="{x:Type Run}">
<Style.Setters>
<Setter Property="Foreground" Value="Blue" />
<Setter Property="TextDecorations" Value="Underline" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="Orange" />
</Trigger>
</Style.Triggers>
</Style>
<htb:HyperlinkTextBlock Background="Transparent"
Margin="10,0,0,0"
HyperlinkStyle="{StaticResource HyperlinkStyle}"
HyperlinkPressed="OnHyperlinkPressed"
Text="{Binding Message, NotifyOnTargetUpdated=True}"
TextWrapping="Wrap" />
private void OnHyperlinkPressed(object sender, HyperlinkPressedEventArgs args)
{
System.Diagnostics.Process.Start(args.Hyperlink.OriginalString);
}
通常由
TextBox. 他们将其风格化TextBlock(删除框架,背景等)使其只读,仅此而已。在这里,您可以选择复制。更新。我想出了一个快速的解决方案
RichTextBox(也许有人会提供更好的,我只是为了):我们这样声明:
Padding="-5"添加以便显示与 匹配TextBlock。而且,当然,可以选择和复制
我不知道这些方法是否正确,但是您可以在按 RMB(或您的选项)时将类型文本添加到 ToolTip,此链接将被复制。或者用 Heder = "Copy link" 组织一个 MenuItem 并调用 copy 方法。根据代码示例,我不知道该给您什么。