WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.199' for table 'wp_options']
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1714392705.3975150585174560546875', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)


Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372
{"id":1424,"date":"2013-05-30T14:07:31","date_gmt":"2013-05-30T12:07:31","guid":{"rendered":"http:\/\/www.jonathanantoine.com\/?p=1424"},"modified":"2013-05-30T14:07:31","modified_gmt":"2013-05-30T12:07:31","slug":"win8xaml-how-to-create-a-textblock-with-clickables-hyperlinks-in-it","status":"publish","type":"post","link":"http:\/\/www.jonathanantoine.com\/2013\/05\/30\/win8xaml-how-to-create-a-textblock-with-clickables-hyperlinks-in-it\/","title":{"rendered":"Win8\/XAML : how to create a TextBlock with clickables hyperlinks in it"},"content":{"rendered":"

Xaml is really powerful and you can build nearly any user interface you want with it. <\/p>\n

However it can be hard sometimes and in this post I will describe how you can create<\/strong> something I first thought it will be easy : a wrapping text with hyperlinks in it<\/strong>. <\/p>\n

Something like this :
\n\"textWrappingWithLinkScreenshot\"<\/p>\n

As you will read, this is not as straightforward as I thought.
\n
\n I tried a few things before to make it works the way I want to.<\/strong><\/p>\n

#fail 1 : use hyperlink element in the Textblock<\/h3>\n

Did you remember Silverlight (:p) ? I do and especially the Hyperlink element<\/a> that you can use in Textblock :
\n[xml]
\n<TextBlock IsReadOnly="True">
\n <Run> Displaying text with<\/Run>
\n <Hyperlink NavigateUri="http:\/\/www.infinitesquare.com"
\n TargetName="_blank">hyperlink<\/Hyperlink>
\n <Run>.<\/Run>
\n<\/TextBlock >
\n[\/xml]<\/p>\n

It’s really nice but…. there is no hyperlink element in the Windows8 Xaml framework<\/strong>… too bad \ud83d\ude41<\/p>\n

#fail 2 : use the tapped event on run elements<\/h3>\n

There is in fact no such thing in the Windows 8 Xaml <\/strong>Framework so this is a dead end \ud83d\ude41<\/p>\n

#fail 3 : use the textblock’s tapped event to retrieve the aimed run element<\/h3>\n

My third idea was to create a textblock with runs and Underline element to recreate the same display.<\/strong><\/p>\n

Then I can register myself to the Tapped event and grab the tapped run and then open the matching links.
\nI would then create something like this :<\/p>\n

[xml]
\n<TextBlock><\/p>\n

\t<Run Text="Cupcake ipsum dolor. Sit amet I love croissant fawork" \/>
\n\t<Run Text=" " \/>
\n\t<Underline FontFamily="Segoe UI">
\n\t\t<Run Foreground="#FFFF1BF5"
\n Text="I love ice cream" \/>
\n\t<\/Underline>
\n\t<Run Text=". Chocolate ice cream souffl\u00e9 pastry." \/>
\n <Run Text=" Bear claw chocolate tart brownie apple pie." \/>
\n\t<LineBreak \/>
\n\t<LineBreak \/>
\n\t<Run Text="Pastry sesame snaps cotton candy jelly-o marzipan pastry" \/>
\n <Run Text=" cake I love faworki. Wypas I love jelly." \/>
\n <Underline FontFamily="Segoe UI">
\n\t\t<Run Foreground="#FFFF1BF5"
\n Text="I love toffee macaroon chocolate bar." \/>
\n\t<\/Underline>
\n<\/TextBlock>
\n[\/xml]<\/p>\n

[csharp]
\nprivate void MyTexBlock_OnTapped(object sender, TappedRoutedEventArgs e)
\n{
\n var run = e.OriginalSource;
\n}
\n[\/csharp]<\/p>\n

The problem here is that the OriginalSource element is in fact the TextBlock itself and not the Run or the Underline element I created. So there is no way to know which link the user touched but only it touched the TextBlock somewhere.<\/strong><\/p>\n

#fail 4 : use a RichTextBlock with InlineUIContainer and an HyperlinkButton element<\/h3>\n

After these failures, I decided to use a weapon of mass destruction : a RichTextBlock and a InlineUIContainer element.
\nYou can’t just add Run inside a RichTextBlock but instead, you have to create one (or more) root paragraph element.<\/p>\n

The InlineUIContainer lets you put any FrameworkElement you want inside a document(the content of the Paragraph). You can then register handlers to the events of this FrameworkElements as you would have in any Xaml UI. <\/p>\n

In the code snippet below, I register myself to Tapped event of the Textblock I insert in my paragraph :
\n[xml]
\n<RichTextBlock IsTextSelectionEnabled="False">
\n <Paragraph>
\n <Run Text="Cupcake ipsum dolor. Sit amet I love croissant fawork" \/>
\n <Run Text=". " \/><\/p>\n

<InlineUIContainer>
\n <Border Background="#FFF1EFEF">
\n <TextBlock Tapped="OnLinkTapped" Foreground="#FFFF1BF5"
\n TextWrapping="Wrap"> <Underline>
\n <Run Text="I love ice cream, to write very long text " \/>
\n <Run Text="and to take some screenshots." \/>
\n <\/Underline>
\n <\/TextBlock>
\n <\/Border>
\n <\/InlineUIContainer><\/p>\n

<Run Text="A Chocolate ice cream souffl\u00e9 pastry. " \/>
\n <Run Text="Bear claw chocolate tart brownie apple pie." \/>
\n <\/Paragraph>
\n<\/RichTextBlock>
\n[\/xml]<\/p>\n

Wonderful… wait … oh no… there is still one issue : the paragraph element will consider the InlineUIContainer as “whole block” and not as “text” and then it will wrap strangely<\/i> your content.<\/strong> In this screenshot, I added a gray border around my TextBlock show this behavior to you :
\n\"shouldBeThere\"<\/p>\n

#Success : use a RichTextBlock and the GetPositionFromPoint method<\/h3>\n

I finally found one hack and if you know a better way, please tell me in the comment which one it is \ud83d\ude42<\/p>\n

My solution is to use the RichTextBlock’s tapped event and its GetPositionFromPoint method<\/strong>. This method returns a TextPointer for a given position of your RichTextBlock. This TextPointer object has a Parent property which is the TextElement (Run, Underline, Span, etc…) the user clicked on : exactly what we want !<\/p>\n

My Xaml then look like this :
\n[xml]<RichTextBlock IsTextSelectionEnabled="False"
\n Margin="30"
\n Width="600"
\n TextAlignment="Justify"
\n FontSize="40"
\n TextWrapping="Wrap"
\n Tapped="UIElement_OnTapped">
\n <Paragraph>
\n <Run Text="Cupcake ipsum dolor. Sit amet I love croissant fawork" \/>
\n <Run Text=". " \/><\/p>\n

<Underline x:Name="LinkToInfiniteSquare"
\n Foreground="#FFFF1BF5">
\n <Run Text="I love ice cream, to write very long text " \/>
\n <Run Text="and to take some screenshots." \/>
\n <\/Underline><\/p>\n

<Run Text="A Chocolate ice cream souffl\u00e9 pastry. " \/><\/p>\n

<Underline x:Name="LinkToMyBlog"
\n Foreground="#FFFF1BF5">
\n <Run Text="Bear claw chocolate tart brownie apple pie." \/>
\n <\/Underline><\/p>\n

<\/Paragraph>
\n<\/RichTextBlock><\/p>\n

[\/xml]<\/p>\n

The last part is to walk trough the parents of the clicked\/touched element to find out its Underline parent, read its name and launch the correct action<\/strong>.<\/p>\n

[csharp]
\nprivate void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
\n{
\n var richTB = sender as RichTextBlock;
\n var textPointer = richTB.GetPositionFromPoint(e.GetPosition(richTB));<\/p>\n

var element = textPointer.Parent as TextElement;
\n while (element != null && !(element is Underline))
\n {
\n if (element.ContentStart != null
\n && element != element.ElementStart.Parent)
\n {
\n element = element.ElementStart.Parent as TextElement;
\n }
\n else
\n {
\n element = null;
\n }
\n }<\/p>\n

if (element == null) return;<\/p>\n

var underline = element as Underline;
\n if (underline.Name == "LinkToInfiniteSquare")
\n {
\n Launcher.LaunchUriAsync(new Uri("http:\/\/www.infinitesquare.com"));
\n }
\n else if (underline.Name == "LinkToMyBlog")
\n {
\n Launcher.LaunchUriAsync(new Uri("http:\/\/www.jonathanantoine.com"));
\n }<\/p>\n

}<\/p>\n

[\/csharp]<\/p>\n

By the way, I can not use a TextBlock element because it does not have the GetPositionFromPoint method.<\/p>\n

Do you know a better way ?<\/h3>\n

(Please don’t tell me to do it in HTML\/JS :p)<\/p>\n

The source code is available here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"

Xaml is really powerful and you can build nearly any user interface you want with it. However it can be hard sometimes and in this post I will describe how you can create something I…<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[35,5],"tags":[14,15,30,34,25,40,24,31],"_links":{"self":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/1424"}],"collection":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/comments?post=1424"}],"version-history":[{"count":18,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/1424\/revisions"}],"predecessor-version":[{"id":1444,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/1424\/revisions\/1444"}],"wp:attachment":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/media?parent=1424"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/categories?post=1424"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/tags?post=1424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}