簡體   English   中英

Xamarin.Forms UWP-在標簽中顯示HTML

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

在Xamarin.Forms中,如何在標簽中顯示HTML? 換句話說,如果我有new Label { Text = "some text and <b>some bold text</b>" } ,我希望它顯示為“一些文本和一些粗體文本 ”。

我知道我需要使用自定義渲染器,並且已經在iOS中實現。 我只是不知道如何在UWP中實現它。

根據您的需求,您可以通過自定義LabelRenderer實現此功能,並且在本機項目中,可以將HtmlTextBehavior用作TextBlock 以下是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;
    }
}

然后,您可以將此行為添加到cusotm渲染器中的本Native Control中。

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

我已經上傳了代碼示例 請檢查。

也許看看這個https://blog.pieeatingninjas.be/2017/11/05/creating-a-hyperlinklabel-in-xamarin-forms/ ...這可能是一個很好的起點還缺少您的需求嗎?

當前,它僅支持超鏈接,但是處理標簽的方式是相同的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM