简体   繁体   English

Xamarin.Forms UWP-在标签中显示HTML

[英]Xamarin.Forms UWP - Display HTML in a Label

In Xamarin.Forms, how do I display HTML in a label? 在Xamarin.Forms中,如何在标签中显示HTML? In other words, if I have new Label { Text = "some text and <b>some bold text</b>" } , I want it to display as "some text and some bold text ". 换句话说,如果我有new Label { Text = "some text and <b>some bold text</b>" } ,我希望它显示为“一些文本和一些粗体文本 ”。

I know I need to use a custom renderer, and I've implemented in iOS. 我知道我需要使用自定义渲染器,并且已经在iOS中实现。 I just don't know how to implement it in UWP. 我只是不知道如何在UWP中实现它。

For your requirement, you could realize this feature via custom LabelRenderer , and in native project you could make HtmlTextBehavior for TextBlock . 根据您的需求,您可以通过自定义LabelRenderer实现此功能,并且在本机项目中,可以将HtmlTextBehavior用作TextBlock The following is Behavior processing logical. 以下是Behavior处理逻辑。

public class HtmlTextBehavior : Behavior<TextBlock>
{
    private const string ElementA = "A";
    private const string ElementB = "B";
    private const string ElementBr = "BR";
    private const string ElementEm = "EM";
    private const string ElementI = "I";
    private const string ElementP = "P";
    private const string ElementStrong = "STRONG";
    private const string ElementU = "U";
    private const string ElementUl = "UL";
    private const string ElementLi = "LI";
    private const string ElementDiv = "DIV";
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Loaded += OnAssociatedObjectLoaded;
        AssociatedObject.LayoutUpdated += OnAssociatedObjectLayoutUpdated;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Loaded -= OnAssociatedObjectLoaded;
        AssociatedObject.LayoutUpdated -= OnAssociatedObjectLayoutUpdated;
    }

    private void OnAssociatedObjectLayoutUpdated(object sender, object o)
    {
        UpdateText();
    }

    private void OnAssociatedObjectLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        UpdateText();
        AssociatedObject.Loaded -= OnAssociatedObjectLoaded;
    }

    private void UpdateText()
    {
        if (AssociatedObject == null) return;
        if (string.IsNullOrEmpty(AssociatedObject.Text)) return;

        string text = AssociatedObject.Text;

        // Just incase we are not given text with elements.
        string modifiedText = string.Format("<div>{0}</div>", text);

        // reset the text because we will add to it.
        AssociatedObject.Inlines.Clear();
        try
        {
            var element = XElement.Parse(modifiedText);
            ParseText(element, AssociatedObject.Inlines);
        }
        catch (Exception)
        {
            // if anything goes wrong just show the html
            AssociatedObject.Text = text;
        }
        AssociatedObject.LayoutUpdated -= OnAssociatedObjectLayoutUpdated;
        AssociatedObject.Loaded -= OnAssociatedObjectLoaded;
    }
    private static void ParseText(XElement element, InlineCollection inlines)
    {
        if (element == null) return;

        InlineCollection currentInlines = inlines;
        var elementName = element.Name.ToString().ToUpper();
        switch (elementName)
        {
            case ElementA:
                var link = new Hyperlink();
                var href = element.Attribute("href");
                if (href != null)
                {
                    try
                    {
                        link.NavigateUri = new Uri(href.Value);
                    }
                    catch (System.FormatException) { /* href is not valid */ }
                }
                inlines.Add(link);
                currentInlines = link.Inlines;
                break;
            case ElementB:
            case ElementStrong:
                var bold = new Bold();
                inlines.Add(bold);
                currentInlines = bold.Inlines;
                break;
            case ElementI:
            case ElementEm:
                var italic = new Italic();
                inlines.Add(italic);
                currentInlines = italic.Inlines;
                break;
            case ElementU:
                var underline = new Underline();
                inlines.Add(underline);
                currentInlines = underline.Inlines;
                break;
            case ElementBr:
                inlines.Add(new LineBreak());
                break;
            case ElementP:
                // Add two line breaks, one for the current text and the second for the gap.
                if (AddLineBreakIfNeeded(inlines))
                {
                    inlines.Add(new LineBreak());
                }

                Span paragraphSpan = new Span();
                inlines.Add(paragraphSpan);
                currentInlines = paragraphSpan.Inlines;
                break;
            case ElementLi:
                inlines.Add(new LineBreak());
                inlines.Add(new Run { Text = " • " });
                break;
            case ElementUl:
            case ElementDiv:
                AddLineBreakIfNeeded(inlines);
                Span divSpan = new Span();
                inlines.Add(divSpan);
                currentInlines = divSpan.Inlines;
                break;
        }
        foreach (var node in element.Nodes())
        {
            XText textElement = node as XText;
            if (textElement != null)
            {
                currentInlines.Add(new Run { Text = textElement.Value });
            }
            else
            {
                ParseText(node as XElement, currentInlines);
            }
        }
        // Add newlines for paragraph tags
        if (elementName == "ElementP")
        {
            currentInlines.Add(new LineBreak());
        }
    }
    private static bool AddLineBreakIfNeeded(InlineCollection inlines)
    {
        if (inlines.Count > 0)
        {
            var lastInline = inlines[inlines.Count - 1];
            while ((lastInline is Span))
            {
                var span = (Span)lastInline;
                if (span.Inlines.Count > 0)
                {
                    lastInline = span.Inlines[span.Inlines.Count - 1];
                }
            }
            if (!(lastInline is LineBreak))
            {
                inlines.Add(new LineBreak());
                return true;
            }
        }
        return false;
    }
}

And then you could add this behavior to Native Control in cusotm renderer. 然后,您可以将此行为添加到cusotm渲染器中的本Native Control中。

protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
    base.OnElementChanged(e);
    HtmlTextBehavior behavior = new HtmlTextBehavior();      
    Interaction.GetBehaviors(Control).Add(behavior);
}

I have uploaded code sample . 我已经上传了代码示例 Please check. 请检查。

Maybe take a look at this https://blog.pieeatingninjas.be/2017/11/05/creating-a-hyperlinklabel-in-xamarin-forms/ ... It could be a good starting point to expand upon on what is still missing for your needs? 也许看看这个https://blog.pieeatingninjas.be/2017/11/05/creating-a-hyperlinklabel-in-xamarin-forms/ ...这可能是一个很好的起点还缺少您的需求吗?

Currently it only supports hyperlinks, but the way to handle the tag would be the same. 当前,它仅支持超链接,但是处理标签的方式是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 HTML 内的可点击超链接 Label Xamarin.Forms - Clickable HTML hyperlink within Label Xamarin.Forms 标签中的 Xamarin 表单 HTML - Xamarin Forms HTML in Label 如何使用 Z625CF3DD56A22D59D9169542CEE6B9 将 html 从 json 文件转换为 xaml 并将其显示 - How to convert and display html from a json file to xaml with xamarin.forms xamarin forms,加£到label - xamarin forms, add £ to label Xamarin Forms: Html label is showing blank content in ios - Xamarin Forms: Html label is showing blank content in ios 如何在Xamarin.Forms中创建与位置相同的UI块:已在HTML中修复? - How to create UI block in Xamarin.Forms same as position: fixed in HTML? 如何在 Xamarin.Forms 中获取 iOS 和 Android 的辅助功能字体大小,以便我可以在 HTML WebView 中更改字体大小? - How to get the accessibility font size for iOS and Android in Xamarin.Forms so I can change font-size in a HTML WebView? Is there an equivalent of html datalist in Xamarin.Forms, mechanism that would allow to select predefined values but also a free-text entry? - Is there an equivalent of html datalist in Xamarin.Forms, mechanism that would allow to select predefined values but also a free-text entry? 在运行时绑定 Xamarin Forms 中标签的 FormattedString 跨度 - Bind a span of a FormattedString of a Label in Xamarin Forms at runtime HTML表单显示注释 - HTML Forms to display comments
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM