簡體   English   中英

C# WPF RichTextBox - 超鏈接

[英]C# WPF RichTextBox - Hyperlinks

我正在尋找一種方法來自動檢測 WPF 中 RichTextBoxes 中的超鏈接(或者如果有一個適合它的類似控件,我會接受它......只需要一個 TextBox)。

我知道這些解決方案: - 在 RichTextBox 中單擊超鏈接而不按住 CTRL - WPF - WPF 動態超鏈接 RichTextbox

但我的問題是,我使用雙向綁定來動態地將 RichTextBoxes 添加到 ItemControl。 我的數據模板看起來像這樣:

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

當我想包含可點擊的超鏈接時,我需要添加它們

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

但是由於我只使用上面顯示的文本的數據綁定 - 而且我不知道另一種解決方案 - 使用定義的數據模板,我不能使用它。 關鍵還在於我需要在一個 RichTextBox 中混合普通文本和超鏈接。

我會很感激任何幫助,謝謝!

您可以使用附加屬性來啟用與RichTextBox的數據綁定。 然后在檢查string值的類型后,實現一個IValueConverter以從string轉換為適當的FlowDocument

富文本框.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)));
  }
}

主窗口.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