static void ProcessMessage(MessageData data, Paragraph messageParagraph, bool append, bool isBold) { List <string> urls = new List <string>(); List <int> indices = new List <int>(); string[] parts = data.Message.Split(' '); foreach (string part in parts) { if (Regex.IsMatch(part, @"(((file|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://)|(www\.))+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[a-zA-Z0-9\&%_\./-~-]*)?", RegexOptions.IgnoreCase) /*Regex.IsMatch(part, @"^(http|https|ftp|)\://|[a-zA-Z0-9\-\.]+\.[a-zA-Z](:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*[^\.\,\)\(\s]$")*/) { urls.Add(part); } } if (urls.Count > 0) { foreach (string url in urls) { indices.Add(data.Message.IndexOf(url)); data.Message = data.Message.Replace(url, ""); } messageParagraph.AddMessage(data.Message, append, isBold); Inline inline = messageParagraph.Inlines.LastInline; for (int i = indices.Count; i-- > 0;) { string url = urls[i]; int index = append ? indices[i] + 1 : indices[i]; Run run = new Run(url); TextPointer pointer = new TextRange(inline.ContentStart, inline.ContentEnd).Text == "\n" ? inline.ContentEnd : inline.ContentStart; Hyperlink link = new Hyperlink(run, pointer.GetPositionAtOffset(index)); link.IsEnabled = true; link.Click += delegate(object sender, RoutedEventArgs args) { try { Process.Start(url); } catch { } }; } } else { messageParagraph.AddMessage(data.Message, append, isBold); } }