Don’t you just hate it when you realize that you not only knew the answer to a question that stumped you all day, but you had actually written it up and posted it to StackOverflow months ago?
Well, in an effort to get the answer to stick inside my very tiny brain, I’m writing it up here on the Infovark Underground as well.
The problem in question had to do with text wrapping in XAML Hyperlinks. And here’s the answer I posted at the time.
And now here’s my more complete recap so that I hopefully never, ever forget it again.
Getting Hyperlink text to wrap properly in WPF or Silverlight can be tricky. Depending on how you’ve structured your XAML, the technique you use for wrapping a Hyperlink can change a lot.
First, recall that you can’t use a Hyperlink element in a XAML file like an ordinary user control. It has to be embedded within a FlowDocument or a TextBlock. It typically looks something like this:
By default, the text of the hyperlink will appear on a single line.
If the code above matches your situation, simply adding TextWrapping=”Wrap” to the TextBlock gives you the desired result.
But suppose you had this scenario:
You might be surprised to find that the the TextWrapping=”Wrap” attribute has no effect at all on the inner TextBlock. The text stretches out in a single line.
No worries, you think, I’ll just move the TextWrapping=”Wrap” bit to the inner TextBlock, like so.
This will wrap your text, all right. But it won’t wrap the underline for the hyperlink. Check it out:
What’s going on here? Why does the first, simple scenario work, and everything else fail in odd ways?
The answer is that the text contents of the Hyperlink element get placed within a hidden Run element in the first case. This creation of an implied Run element happens frequently in the framework. It happens so often that most of the time you forget it’s doing it.
Sure enough, if you replace the inner TextBlock with a Run in our second scenario, you get a lovely text-wrapped link.
Here’s the markup:
And here’s our desired result:
Now I know what you’re thinking. You’re wondering what to do if you actually need that inner element to be TextBlock. What if you’re working with an older version of WPF or Silverlight, where the Run.Text property couldn’t be data-bound? Or what if you wanted to apply formatting to the text of the link, like bold or italics, neither of which are supported by Run?
Then it gets ugly. You’ll need something like the following code, which removes the underline from the Hyperlink element and reapplies it at the inner TextBlock.
This solution isn’t perfect; sometimes you’ll see the underline jiggle a bit as you resize your window. But it’s as close as we can get it for now.
Who would have thought something as simple as a hyperlink with wrapped text could be so difficult?
Leave a Comment