2016-01-15 3 views
0

Я видел несколько сообщений в разных формах, различающихся по времени от 2006 года до теперь о том, как добавлять гиперссылки в RichTextBox, но все они кажутся слишком сложными для того, что я хочу. Я создаю клиент для настольных чатов, и я получаю входные данные как строки, теперь среди этих строк могут быть некоторые URL-адреса, мне нужны эти URL-адреса для обращения. Который из того, что я собираю, означает, что они должны быть объектами HyperLink.WPF Dynamic HyperLinks RichTextbox

Навигация по RichTextBox и замена URL-адресов с помощью HyperLinks - это не маленький подвиг. У кого-то есть относительно простое решение для этого?

В моем веб-клиенте это просто один лайнер

value = value.replace(/(http:\/\/[^\s]+)/gi, '<a href="$1" target="_blank">$1</a>'); 

Никогда не думал, что увижу тот день, когда C# на самом деле делает его более трудным.

+0

Для большей ясности RichTextBox вас беспокоит источник ввода пользователя? Или вы беспокоитесь о RichTextBox, который будет частью, которая показывает полный разговор? Или оба? – Rowbear

+0

@Rowbear Я был в основном обеспокоен отображением разговора с гиперссылками, поскольку их кликабельность во входном файле richtextbox была бы дополнительным бонусом, но обязательно требованием. – Nathan

ответ

0

Если вы хотите сделать эквивалент value.replace(/(http:\/\/[^\s]+)/gi, '<a href="$1" target="_blank">$1</a>') в WPF:

<RichTextBox x:Name="MyRichTextBox" IsDocumentEnabled="True" IsReadOnly="True" /> 

И код, который преобразует строку состоит в следующем:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     var htmlText = "Google's website is http://www.google.com"; 
     MyRichTextBox.Document = ConvertToFlowDocument(htmlText); 
    } 

    private FlowDocument ConvertToFlowDocument(string text) 
    { 
     var flowDocument = new FlowDocument(); 

     var regex = new Regex(@"(http:\/\/[^\s]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase); 
     var matches = regex.Matches(text).Cast<Match>().Select(m => m.Value).ToList(); 

     var paragraph = new Paragraph(); 
     flowDocument.Blocks.Add(paragraph); 

     foreach (var segment in regex.Split(text)) 
     { 
      if (matches.Contains(segment)) 
      { 
       var hyperlink = new Hyperlink(new Run(segment)) 
       { 
        NavigateUri = new Uri(segment), 
       }; 
       hyperlink.RequestNavigate += (sender, args) => Process.Start(segment); 

       paragraph.Inlines.Add(hyperlink); 
      } 
      else 
      { 
       paragraph.Inlines.Add(new Run(segment)); 
      } 
     } 

     return flowDocument; 
    } 
} 

Он использует тот же регулярное выражение, при условии, который отсутствует, если вы правильно хотите распознавать URL-адреса с регулярным выражением. Это не признает https, а последняя точка в следующем предложении будет частью URL-адреса: "This is a URL: http://www.google.com/."

Что делает код, чтобы разделить текст на основе регулярного выражения, повторить его и добавить правильное элементы на FlowDocument, построенные на лету.

При нажатии на кнопку Hyperlink следует открыть браузер по умолчанию.

Результат:

Result

Тем не менее, это только хорошо для чтения только использование в RichTextBox (как показано на вопрос в комментарии).

+0

У меня есть отдельное регулярное выражение для моего веб-клиента, который делает https, в основном то же самое, но с https вместо http. Да, это будет для контекста только для чтения, поскольку мне просто нужно его щелкнуть, как только он получен не при отправке. Я попробую, спасибо за ваш ответ, хотя, я дам вам знать, как это происходит :) – Nathan

+0

Ваше решение было просто застенчивым! Я добавил параметр, чтобы принять документ потока, поэтому я могу добавить к существующему документу flow в документе RichTextBox. Большое вам спасибо, я новичок в WPF и, безусловно, никогда ничего не делал с FlowDocuments. PS. Я добавил s? к моему регулярному выражению, чтобы он распознал https, если кто-то оставляет точку в конце URL-адреса, – Nathan