How to Make a Hyperlink Work in a Richtextbox

Add clickable hyperlinks to a RichTextBox without new paragraph

OK, looks like here is what I need (thanks @Blam and @PaulN Dynamically adding hyperlinks to a RichTextBox):

    public MainWindow()
{
InitializeComponent();

rtb.IsDocumentEnabled = true;
rtb.Document.Blocks.FirstBlock.Margin = new Thickness(0);
}

private void AddHyperlinkText(string linkURL, string linkName,
string TextBeforeLink, string TextAfterLink)
{
Paragraph para = new Paragraph();
para.Margin = new Thickness(0); // remove indent between paragraphs

Hyperlink link = new Hyperlink();
link.IsEnabled = true;
link.Inlines.Add(linkName);
link.NavigateUri = new Uri(linkURL);
link.RequestNavigate += (sender, args) => Process.Start(args.Uri.ToString());

para.Inlines.Add(new Run("[" + DateTime.Now.ToLongTimeString() + "]: "));
para.Inlines.Add(TextBeforeLink);
para.Inlines.Add(link);
para.Inlines.Add(new Run(TextAfterLink));

rtb.Document.Blocks.Add(para);
}

private void button1_Click(object sender, RoutedEventArgs e)
{
AddHyperlinkText("http://www.google.com", "http://www.google.com",
"Please visit ", ". Thank you! Some vAdd clickable hyperlinks to a RichTextBox without new paragraph Links inside rich textbox? Hyperlink to a line of RichTextBox in C# How to insert hyperlinks in Rich Texeery looooooong text.");
}

Sample Image

But one little problem left: maybe someone know how to remove blank space at the beginning which is marked with the red line on the image above?

Links inside rich textbox?

Of course it is possible by invoking some WIN32 functionality into your control, but if you are looking for some standard ways, check this post out:
Create hyperlink in TextBox control

There are some discussions about different ways of integration.

greetings

Update 1:
The best thing is to follow this method:
http://msdn.microsoft.com/en-us/library/f591a55w.aspx

because the RichText box controls provides some functionality to "DetectUrls". Then you can handle the clicked links very easy:

this.richTextBox1.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBox1_LinkClicked);

and you can simple create your own RichTextBox contorl by extending the base class - there you can override the methods you need, for example the DetectUrls.

Hyperlink to a line of RichTextBox in C#

No, this will not work unless you code the necessary stuff yourself.

Two suggestions:

  • A simple workaround with links always starting with www.
  • The nicer solution with arbitrary link text

Let's have a look at both options..:

  • Using the built-in functionality of recognizing an URL seems the right way to start, but the link will always have to look like a URL, not like a hyperlink to an anchor.. If you can live with a solution that has, say, links like this: www.goto.234 and anchors like this: #234# this is really rather simple..

A working example can be as simple as this:

private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
var s = e.LinkText.Split('.');
string anchor = s[2];

int a = richTextBox1.Text.IndexOf("#" + anchor + "#" );
if (a >= 0) richTextBox1.SelectionStart = a; else return; // do add more checks!
richTextBox1.SelectionLength = 0;
Text = anchor + " @ " + a;
//richTextBox1.ScrollToCaret(); <<--- this crashes on my machine!
// so I take the jump out of the click event and it works:
Timer ttt = new Timer() { Interval = 100 };
ttt.Tick += (ss, ee) => { richTextBox1.ScrollToCaret(); ttt.Stop(); };
}
  • Option two: If you'd rather have more choice of how the links should read you can do this:

Start by formatting each to

  • Start with a special character, say a tilde '~'
  • format it to look blue and underlined if you want to
  • Either make it one word or replace space by underlines and format those to have the forecolor equal to the backcolor

Now this can do the job:

public string delimiters = " ()[]{}!&?=/\\,;.\r\n";

private void richTextBox2_Click(object sender, EventArgs e)
{
int sstart = -1;
string s = getWordAt(richTextBox2.Text,
richTextBox2.SelectionStart, delimiters, out sstart);
if (s.Length < 3) return;
string char1 = s.Substring(0, 1);
if (char1 == "~")
{
int p = richTextBox2.Text.IndexOf("#" + s.Substring(1));
if (p >= 0) { richTextBox2.SelectionStart = p; richTextBox2.ScrollToCaret(); }
}
}

public static string getWordAt(string text, int cursorPos,
string delimiters, out int selStart)
{
int startPos = 0;
selStart = startPos;
if ((cursorPos < 0) | (cursorPos > text.Length) | (text.Length == 0)) return "";
if ((text.Length > cursorPos) & (delimiters.Contains(text[cursorPos]))) return "";
int endPos = text.Length - 1;
if (cursorPos == text.Length) endPos = text.Length - 1;
else { for (int i = cursorPos; i < text.Length; i++)
{ if (delimiters.Contains(text[i])) { endPos = i - 1; break; } } }
if (cursorPos == 0) startPos = 0;
else { for (int i = cursorPos; i > 0; i--)
{ if (delimiters.Contains(text[i])) { startPos = i + 1; break; } } }
selStart = startPos;

return text.Substring(startPos, endPos - startPos + 1);
}

Here are the two versions side by side, once at the top then after clicking on a link:

Sample ImageSample Image

Both versions work fine, although both could do with some more checks.

Note that I was too lazy to format the pseudo-links in the second example, so they show their tildes and hashes..

Not hard to write a helper function that can insert the formatting; the search will still work as it searches in the Text, not the Rtf property..

How to insert hyperlinks in Rich Text Box in RTF format

For WinForms you can try to use LinkLabel

LinkLabel link = new LinkLabel();
link.Text = "Microsoft";
LinkLabel.Link data = new LinkLabel.Link();
data.LinkData = "https://www.microsoft.com/";
link.Links.Add(data);
link.Location = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength);
richTextBox1.Controls.Add(link);

For WPF you have to insert hyperlinks like Hyperlink not like text:

Paragraph parx = new Paragraph();
Run run1 = new Run("Text preceeding the hyperlink.");
Run run2 = new Run("Text following the hyperlink.");
Run run3 = new Run("Link Text.");

Hyperlink hyperl = new Hyperlink(run3);
hyperl.NavigateUri = new Uri("http://search.msn.com");

parx.Inlines.Add(run1);
parx.Inlines.Add(hyperl);
parx.Inlines.Add(run2);

Adding a paragraph to the RichTextBox should look like

richTextBox1.IsDocumentEnabled = true;
richTextBox1.Document.Blocks.Add(parx);

Clicking HyperLinks in a RichTextBox without holding down CTRL - WPF

Managed to find a way around this, pretty much by accident.

The content that's loaded into my RichTextBox is just stored (or inputted) as a plain string. I have subclassed the RichTextBox to allow binding against it's Document property.

What's relevant to the question, is that I have an IValueConverter Convert() overload that looks something like this (code non-essential to the solution has been stripped out):

FlowDocument doc = new FlowDocument();
Paragraph graph = new Paragraph();

Hyperlink textLink = new Hyperlink(new Run(textSplit));
textLink.NavigateUri = new Uri(textSplit);
textLink.RequestNavigate +=
new System.Windows.Navigation.RequestNavigateEventHandler(navHandler);

graph.Inlines.Add(textLink);
graph.Inlines.Add(new Run(nonLinkStrings));

doc.Blocks.Add(graph);

return doc;

This gets me the behavior I want (shoving plain strings into RichTextBox and getting formatting) and it also results in links that behave like a normal link, rather than one that's embedded in a Word document.

Getting Hyperlinks Working in Rich Text Box Using RTF

An easy way for getting rtfs to work is to write your text in Microsoft word, copy & paste it to Wordpad and the saving it as a RTF from there.
The detour with MS Word is needed, because WordPad does not support entering links in the UI, although it handles them correctly when they come from other sources, like the clipboard. Also, MS Word creates massively bloated rtf.

The rtf file you create this way can then be opened in any text editor and can be used as a string constant in your program.

In your case, I suppose that the prefix and maybe the color table are missing and are causing the problem.

By the way: Wordpad is not much more than a wrapper around the Windows rtf control, i.e. the same control that you are using in your code.



Related Topics



Leave a reply



Submit