@@ -84,6 +84,8 @@ internal static IEnumerable<UIElement> VisitChildren(MarkupNode parent, EventHan
8484 }
8585 }
8686
87+ // CreateBlock builds a view for a single *blocky* node. It is called for nodes that are
88+ // blocks themselves (List/Table/Block/Divider/Image) and also for nodes that contain block descendants.
8789 private static FrameworkElement CreateBlock ( MarkupNode node , EventHandler < Uri > ? urlClickHandler )
8890 {
8991 // Create a view for a single block node.
@@ -167,6 +169,51 @@ private static FrameworkElement CreateBlock(MarkupNode node, EventHandler<Uri>?
167169 imageElement . Source = imageSource ;
168170 return imageElement ;
169171
172+ case MarkupType . Link :
173+ // If the link wraps block content (like <img>), render it as a HyperlinkButton
174+ if ( Uri . TryCreate ( node . Content , UriKind . Absolute , out var linkUri ) )
175+ {
176+ var linkButton = new HyperlinkButton
177+ {
178+ Padding = new Thickness ( 0 ) ,
179+ BorderThickness = new Thickness ( 0 ) ,
180+ Background = null
181+ } ;
182+ if ( urlClickHandler != null )
183+ linkButton . Click += ( s , e ) => urlClickHandler ( s , linkUri ) ;
184+
185+ // Build the content from the children as blocks
186+ FrameworkElement content ;
187+ if ( node . Children . Count == 1 )
188+ {
189+ var child = node . Children [ 0 ] ;
190+ child . InheritAttributes ( node ) ;
191+ content = CreateBlock ( child , urlClickHandler ) ;
192+ }
193+ else
194+ {
195+ var panel = new StackPanel ( ) ;
196+ foreach ( var child in node . Children )
197+ {
198+ child . InheritAttributes ( node ) ;
199+ panel . Children . Add ( CreateBlock ( child , urlClickHandler ) ) ;
200+ }
201+ content = panel ;
202+ }
203+
204+ linkButton . Content = content ;
205+ return linkButton ;
206+ }
207+
208+ // If the href isn't a clickable URI, just render children normally
209+ var fallback = new StackPanel ( ) ;
210+ foreach ( var child in node . Children )
211+ {
212+ child . InheritAttributes ( node ) ;
213+ fallback . Children . Add ( CreateBlock ( child , urlClickHandler ) ) ;
214+ }
215+ return fallback ;
216+
170217 default :
171218 return new Border ( ) ; // placeholder for unsupported things
172219 }
@@ -205,6 +252,8 @@ private static TextBlock CreateFormattedText(IEnumerable<MarkupNode> nodes, Even
205252 return tb ;
206253 }
207254
255+ // Flattens an *inline-only* subtree into text spans for a single TextBlock.
256+ // It is only used when VisitChildren has verified there are no block elements underneath.
208257 private static IEnumerable < Span > VisitInline ( MarkupNode node , EventHandler < Uri > ? urlClickHandler )
209258 {
210259 // Converts a single inline node into a sequence of spans.
@@ -308,7 +357,7 @@ private static Grid ConvertTableToGrid(MarkupNode table, EventHandler<Uri>? urlC
308357 if ( attr . TryGetValue ( "rowspan" , out var rowSpanStr ) && ushort . TryParse ( rowSpanStr , out var rowSpanFromAttr ) )
309358 {
310359 rowSpan = rowSpanFromAttr ;
311- Grid . SetRowSpan ( cellView , colSpan ) ;
360+ Grid . SetRowSpan ( cellView , rowSpan ) ;
312361 }
313362 Grid . SetRow ( cellView , curRow ) ;
314363 Grid . SetColumn ( cellView , curCol ) ;
@@ -358,9 +407,9 @@ private static void ApplyStyle(Span el, MarkupNode node)
358407 el . FontWeight = FontWeights . Normal ;
359408
360409 if ( node . IsItalic == true )
361- el . FontStyle | = FontStyle . Italic ;
410+ el . FontStyle = FontStyle . Italic ;
362411 else if ( node . IsItalic == false )
363- el . TextDecorations |= ~ TextDecorations . Underline ;
412+ el . FontStyle = FontStyle . Normal ;
364413
365414 if ( node . IsUnderline == true )
366415 el . TextDecorations |= TextDecorations . Underline ;
@@ -386,14 +435,14 @@ private static void ApplyStyle(TextBlock el, MarkupNode node)
386435 el . FontWeight = FontWeights . Normal ;
387436
388437 if ( node . IsItalic == true )
389- el . FontStyle | = FontStyle . Italic ;
438+ el . FontStyle = FontStyle . Italic ;
390439 else if ( node . IsItalic == false )
391- el . FontStyle |= ~ FontStyle . Italic ;
440+ el . FontStyle = FontStyle . Normal ;
392441
393442 if ( node . IsUnderline == true )
394443 el . TextDecorations |= TextDecorations . Underline ;
395444 else if ( node . IsUnderline == false )
396- el . TextDecorations | = ~ TextDecorations . Underline ;
445+ el . TextDecorations & = ~ TextDecorations . Underline ;
397446
398447 if ( node . FontColor . HasValue )
399448 el . Foreground = new SolidColorBrush ( ) { Color = ConvertColor ( node . FontColor . Value ) } ;
0 commit comments