Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clicking HyperLinks in a RichTextBox without holding down CTRL - WPF

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.

like image 591
John Noonan Avatar asked Apr 17 '09 21:04

John Noonan


4 Answers

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.

like image 177
JHubbard80 Avatar answered Nov 02 '22 05:11

JHubbard80


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 Hyperlinks inside the RichTextBox. The essential is to use a EventSetter to make the Hyperlinks 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.

like image 15
hillin Avatar answered Nov 02 '22 05:11

hillin


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.

like image 5
John Noonan Avatar answered Nov 02 '22 03:11

John Noonan


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>
like image 1
BionicCode Avatar answered Nov 02 '22 04:11

BionicCode