I would like to be able to add some HTML into a Xamarin.Forms page? Is this possible? Also is it possible to add this as part of a label?
1 Answers
Answers 1
If you want full-blown html support, then Xamarin forms WebView
would be way to go. But if you want some basic formatting support in Label
as it's native counter-parts (TextView
in android, and UILabel
in iOS) do, you can implement renderers for that.
Forms control
public class HtmlLabel : Label { public static readonly BindableProperty HtmlProperty = BindableProperty.Create( "Html", typeof(string), typeof(HtmlLabel), defaultValue: default(string)); public string Html { get { return (string)GetValue(HtmlProperty); } set { SetValue(HtmlProperty, value); } } }
iOS renderer
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))] namespace HtmlLabelApp.iOS { public class HtmlLabelRenderer : LabelRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Label> e) { base.OnElementChanged(e); //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control if (e.NewElement != null) UpdateTextOnControl(); } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); //if there is change in text or font-style, trigger update to redraw control if (e.PropertyName == nameof(HtmlLabel.Html)) { UpdateTextOnControl(); } } void UpdateTextOnControl() { if (Control == null) return; if (Element is HtmlLabel formsElement) { //set new text with ui-style-attributes to native control (UILabel) var htmlString = new NSString(formsElement.Html ?? string.Empty); var htmlData = htmlString.Encode(NSStringEncoding.UTF8); var attr = new NSAttributedStringDocumentAttributes { DocumentType = NSDocumentType.HTML }; var error = new NSError(); var dict = new NSDictionary(); var attributedString = new NSAttributedString(htmlData, attr, out dict, ref error); Control.AttributedText = attributedString; } } } }
Android renderer
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))] namespace HtmlLabelApp.Droid { public class HtmlLabelRenderer : LabelRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Label> e) { base.OnElementChanged(e); //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control if (e.NewElement != null) UpdateTextOnControl(); } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); //if there is change in text or font-style, trigger update to redraw control if (e.PropertyName == nameof(HtmlLabel.Html)) { UpdateTextOnControl(); } } void UpdateTextOnControl() { if (Control == null) return; if (Element is HtmlLabel formsElement) { var htmlAsString = formsElement.Html ?? string.Empty; // used by WebView var htmlAsSpanned = Html.FromHtml(htmlAsString, FromHtmlOptions.ModeCompact); // used by TextView Control.TextFormatted = htmlAsSpanned; } } } }
Sample Usage
<local:HtmlLabel BackgroundColor="Silver"> <local:HtmlLabel.Html> <x:String> <![CDATA[ <h1>Main Title</h1> <h2>A sub-title</h2> <p>This is some html. Look, here\'s an <u>underline</u>.</p> <p>Look, this is <em>emphasized.</em> And here\'s some <b>bold</b>.</p> <p>This is a UL list: <ul> <li>One</li> <li>Two</li> <li>Three</li> </ul> <p>This is an OL list: <ol> <li>One</li> <li>Two</li> <li>Three</li> </ol> ]]> </x:String> </local:HtmlLabel.Html> </local:HtmlLabel>
0 comments:
Post a Comment