I have a WPF RichTextBox with isReadOnly
set to True
. I would like users to be able to click on HyperLinks contained within the RichTextBox, without them having to hold down Ctrl.
The Click event on the HyperLink doesn't seem to fire unless Ctrl is held-down, so I'm unsure of how to proceed.
I found a solution. Set IsDocumentEnabled to "True" and set IsReadOnly to "True".
<RichTextBox IsReadOnly="True" IsDocumentEnabled="True" />
Once I did this, the mouse would turn into a 'hand' when I hover over a text displayed within a HyperLink tag. Clicking without holding control will fire the 'Click' event.
I am using WPF from .NET 4. I do not know if earlier versions of .NET do not function as I describe above.
JHubbard80's answer is a possible solution, it's the easiest way if you do not need the content to be selected.
However I need that :P here is my approach: set a style for the Hyperlink
s inside the RichTextBox
. The essential is to use a EventSetter
to make the Hyperlink
s handling the MouseLeftButtonDown
event.
<RichTextBox>
<RichTextBox.Resources>
<Style TargetType="Hyperlink">
<Setter Property="Cursor" Value="Hand" />
<EventSetter Event="MouseLeftButtonDown" Handler="Hyperlink_MouseLeftButtonDown" />
</Style>
</RichTextBox.Resources>
</RichTextBox>
And in codebehind:
private void Hyperlink_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
var hyperlink = (Hyperlink)sender;
Process.Start(hyperlink.NavigateUri.ToString());
}
Thanks to gcores for the inspiaration.
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.
Do not handle any mouse events explicitly and do not force the cursor explicitly - like suggested in every answer.
It's also not required to make the complete RichTextBox
read-only (as suggested in another answer).
To make the Hyperlink
clickable without pressing the Ctrl key, the Hyperlink
must be made read-only e.g., by wrapping it into a TextBlock
(or alternatively by making the complete RichTextBox
read-only, of course).
Then simply handle the Hyperlink.RequestNavigate
event or/and attach an ICommand
to the Hyperlink.Command
property:
<RichTextBox IsDocumentEnabled="True">
<FlowDocument>
<Paragraph>
<Run Text="Some editable text" />
<TextBlock>
<Hyperlink NavigateUri="https://duckduckgo.com"
RequestNavigate="OnHyperlinkRequestNavigate">
DuckDuckGo
</Hyperlink>
</TextBlock>
</Paragraph>
</FlowDocument>
</RichTextBox>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With