C#WPF RichTextBox-超链接

问题描述 投票:0回答:1

[我正在寻找一种在WPF中自动检测RichTextBoxes中的超链接的方法(或者,如果有适合它的辅助控件,我认为...只需要一个TextBox)。

我知道以下解决方案:-Clicking HyperLinks in a RichTextBox without holding down CTRL - WPF-WPF Dynamic HyperLinks RichTextbox

但是我的问题是,我正在使用双向绑定以便将RichTextBoxes动态添加到ItemControl。我的DataTemplate看起来像这样:

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

[当我想包括可单击的超链接时,我需要添加它们与

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

但是由于我仅使用上面显示的文本进行数据绑定-并且我不知道另一种解决方案-使用已定义的数据模板,因此无法使用它。重点还在于,我需要在一个RichTextBox中混合普通文本和超链接。

感谢您的帮助,谢谢!

c# wpf textbox richtextbox
1个回答
0
投票

您可以使用附加属性来将数据绑定到RichTextBox。然后,在检查IValueConverter值的类型后,实施stringFlowDocument转换为适当的string

RichTextBox.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

[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

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

  <RichTextBox RichTextBox.DocumentSource="{Binding MyDataText, Converter={StaticResource StringToFlowDocumentConverter}" />
</Window>
© www.soinside.com 2019 - 2024. All rights reserved.