简体   繁体   中英

Hyperlink in TextBlock is is not clickable

I have made this in code-behind:

var finishedText = new Run("Some text");
var finishedUrl = new Run("http://somewhere");

var hyperlink = new Hyperlink(finishedUrl) { NavigateUri = new Uri("http://somewhere") };

hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(hyperlink);
FinishedTextBlock.Inlines.Add(Environment.NewLine);
FinishedTextBlock.Inlines.Add(finishedUrl);

In XAML:

<TextBlock Grid.Row="0"
           x:Name="FinishedTextBlock"
           Width="Auto"
           Margin="10 10 0 0">
</TextBlock>

The text is not clickable.

在此处输入图像描述

What am I doing wrong?

The text is not clickable.

That is because your Hyperlink text is not even shown. You see the last Run that you have added to the Inlines collection, not the hyperlink itself.

You add the same Run named finishedUrl to your Hyperlink and its containing TextBlock , but you have to create a separate Run instance for the Hyperlink .

var finishedText = new Run("Some text");
var finishedUrl = "http://somewhere";
var finishedUrlRun = new Run(finishedUrl);

var hyperlink = new Hyperlink(finishedUrlRun) { NavigateUri = new Uri("http://somewhere") };

hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(hyperlink);
FinishedTextBlock.Inlines.Add(Environment.NewLine);

var finishedUrlRun1 = new Run(finishedUrl);
FinishedTextBlock.Inlines.Add(finishedUrlRun1);

Even better, just do not add the last Run , as it is redundant, and replace the NewLine with a LineBreak to get the same layout as in your image but with a link.

FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(new LineBreak());
FinishedTextBlock.Inlines.Add(hyperlink);

Unless your hyperlink is inside a webview then nothing will happen when you click on a hyperlink.

You need to handle the RequestNavigate event and do something before you'll see a web browser appear with a page in it.

If this was a wpf page inside a frame, or navigationwindow then it would also navigate without code.

https://docs.microsoft.com/en-us/dotnet/api/system.windows.documents.hyperlink?view=netcore-3.1

Remarks

Hyperlink implements the NavigateUri property that you set with the Uri of the content that should be navigated to when the Hyperlink is clicked. Hyperlink navigation can only occur, however, if either the direct or indirect parent of a Hyperlink is a navigation host, including NavigationWindow, Frame, or any browser that can host XBAPs (which includes Internet Explorer 6 and later versions, and Firefox 2.0+). For more information, see the Navigation Hosts topic in Navigation Overview.

As it is, you need an event handler.

I'm not clear whether you intend the url to appear or a string. If you want a different string then this should work:

        TextBlock tb = new TextBlock();
        tb.Inlines.Add(new Run {Text="Some text" } );
        tb.Inlines.Add(new LineBreak());
        Run linkRun = new Run("Link To Google");
        Hyperlink hyper = new Hyperlink(linkRun) { NavigateUri = new Uri(@"http://www.google.com") };
        hyper.RequestNavigate += (o, e) => Process.Start(new ProcessStartInfo(e.Uri.ToString()){ UseShellExecute = true }); 
        tb.Inlines.Add(hyper);

If you want the url to appear rather than some other string then:

        TextBlock tb = new TextBlock();
        tb.Inlines.Add(new Run { Text = "Some text" });
        tb.Inlines.Add(new LineBreak());
        string url = @"http://www.google.com";
        Run linkRun = new Run(url);
        Hyperlink hyper = new Hyperlink(linkRun){ NavigateUri = new Uri(url) };
        hyper.RequestNavigate += (o, e) => Process.Start(new ProcessStartInfo(e.Uri.ToString()) { UseShellExecute = true });
        tb.Inlines.Add(hyper);
        sp.Children.Add(tb);

Note

One the process start, you will often get an error on win 10 machines without that useshellexecute in the process startinfo.

In older OS ( and you would see in old SO answers ) you used to be able to just process start with a URL and it would work with the default browser.

There is a linebreak inline which is intended to add a linebreak between a series of runs in a textblock.

In XAML, it needs to be like this:

<TextBlock Grid.Row="0"
    x:Name="FinishedTextBlock"
    Width="Auto"
    Margin="10 10 0 0">
<Run Text="Some text" /> 
<LineBreak/>
<Hyperlink>http://somewhere</Hyperlink>
</TextBlock>

The hyperlink in your code does not content anything. The hyperlink constructor parameter [finishedUrl] did not initialized the hyperlink to contain the string "http://somewhere".

You can change your code something like below:

var finishedText = new Run("Some text");
var finishedUrl = new Run("http://somewhere");

var hyperlink = new Hyperlink() { NavigateUri = new Uri("http://somewhere") };
hyperlink.Inlines.Add(finishedUrl.Text);

hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(Environment.NewLine);
FinishedTextBlock.Inlines.Add(hyperlink);   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM