简体   繁体   English

C# WPF RichTextBox - 超链接

[英]C# WPF RichTextBox - Hyperlinks

I'm looking for a way to autodetect hyperlinks in RichTextBoxes in WPF (or if there is a smiliar control that's suitable for it, I'll take that...just needs to be a TextBox).我正在寻找一种方法来自动检测 WPF 中 RichTextBoxes 中的超链接(或者如果有一个适合它的类似控件,我会接受它......只需要一个 TextBox)。

I'm aware of these solutions: - Clicking HyperLinks in a RichTextBox without holding down CTRL - WPF - WPF Dynamic HyperLinks RichTextbox我知道这些解决方案: - 在 RichTextBox 中单击超链接而不按住 CTRL - WPF - WPF 动态超链接 RichTextbox

But my problem is, that I'm using two-way-binding in order to add dynamically RichTextBoxes to an ItemControl.但我的问题是,我使用双向绑定来动态地将 RichTextBoxes 添加到 ItemControl。 My DataTemplate looks like this:我的数据模板看起来像这样:

<RichTextBox IsDocumentEnabled="True" IsReadOnly="True">
   <FlowDocument>
      <Paragraph>
           <Run Text="{Binding MyDataText}"/>
     </Paragraph>
  </FlowDocument>
</RichTextBox>

When I want to include clickable hyperlinks, I'd need to add them with当我想包含可点击的超链接时,我需要添加它们

<Paragraph>
    <Hyperlink> 
    https://stackoverflow.com
    </Hyperlink>
<Paragraph>

But since I'm using data binding with only the text as shown above - and I'm tbh not aware of another solution - with the defined Data Template, I can't use that.但是由于我只使用上面显示的文本的数据绑定 - 而且我不知道另一种解决方案 - 使用定义的数据模板,我不能使用它。 The point is also that I need to mix normal text AND hyperlinks in one RichTextBox.关键还在于我需要在一个 RichTextBox 中混合普通文本和超链接。

I'd appreciate any help, thanks!我会很感激任何帮助,谢谢!

You can use an attached property to enable data binding to the RichTextBox .您可以使用附加属性来启用与RichTextBox的数据绑定。 Then implement a IValueConverter to convert from string to the appropriate FlowDocument after checking the type of the string value:然后在检查string值的类型后,实现一个IValueConverter以从string转换为适当的FlowDocument

RichTextBox.cs富文本框.cs

public class RichTextBox : DependencyObject
{
  public static readonly DependencyProperty DocumentSourceProperty = DependencyProperty.RegisterAttached(
    "DocumentSource",
    typeof(FlowDocument),
    typeof(RichTextBox),
    new PropertyMetadata(default(string), RichTextBox.OnDocumentSourceChanged));

  public static void SetText([NotNull] DependencyObject attachingElement, FlowDocument value) =>
    attachingElement.SetValue(RichTextBox.DocumentSourceProperty, value);

  public static string GetText([NotNull] DependencyObject attachingElement) =>
    (FlowDocument) attachingElement.GetValue(RichTextBox.DocumentSourceProperty);


  private static void OnDocumentSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    if (!(d is System.Windows.Controls.RichTextBox richTextBox))
    {
      throw new ArgumentException($"Wrong type.\nThe attaching element must be of type {typeof(System.Windows.Controls.RichTextBox)}.");
    }

    Application.Current.Dispatcher.InvokeAsync(
      () => richTextBox.Document = (FlowDocument) e.NewValue,
      DispatcherPriority.DataBind);
  }
}

StringToFlowDocumentConverter.cs StringToFlowDocumentConverter.cs

[ValueConversion(typeof(string), typeof(FlowDocument))]
public class StringToFlowDocumentConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    if (value is string stringValue)
    {
      return stringValue.StartsWith("http", StringComparison.OrdinalIgnoreCase)
        ? CreateHyperlinkDocument(stringValue)
        : CreateTextDocument(stringValue);
    }

    return Binding.DoNothing;
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotSupportedException();
  }

  private FlowDocument CreateHyperlinkDocument(string url)
  {
    return new FlowDocument(new Paragraph(new Hyperlink(new Run(url))));
  }

  private FlowDocument CreateTextDocument(string text)
  {
    return new FlowDocument(new Paragraph(new Run(text)));
  }
}

MainWindow.xaml主窗口.xaml

<Window>
  <Window.Resources>
    <StringToFlowDocumentConverter x:Key="StringToFlowDocumentConverter" />
  </Window.Resources>

  <RichTextBox RichTextBox.DocumentSource="{Binding MyDataText, Converter={StaticResource StringToFlowDocumentConverter}" />
</Window>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM