在富文本框中将字符串与视频标记绑定Windows Phone UWP

时间:2016-08-04 13:34:42

标签: c# xaml windows-phone-8.1

我需要绑定一个在Windows手机组件中有视频标签的字符串。我使用Rich-text box控件来绑定字符串

以下是具有视频标记

的示例字符串
கூறினார்.</div><div><br /></div><div align="center"><object height="360"><embed src="https://www.youtube.com/embed/rprTDfqFwtI" height="360px" width="100%" /></object></div><div>அமைச்சரின் விளக்கத்திற்குப் பிறகும் உறுப்பினர்கள் அதனை ஏற்காமல் அவையின் 

下面是我绑定字符串的XAML代码

xmlns:local="using:NameSpace"

<RichTextBlock IsTextSelectionEnabled="False" local:Properties.Html="{Binding ArticleDetail}"  TextWrapping="Wrap" FontSize="15"
                                   Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
                                           FontFamily="{StaticResource ContentControlThemeFontFamily}"/>

我在我的项目中安装了Nuget的 RichTextBlock.Html2Xaml 。我还在我的项目中添加了 RichTextBlockHtml2Xaml.xslt RichTextBlockProperties.cs 文件项目

RichTextBlockHtml2Xaml.xslt

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <!-- The html root element must be div, it translates to a xaml richtextblock.-->
  <xsl:template match="/div" priority="9">
    <RichTextBlock>
      <RichTextBlock.Resources>
        <Style x:Key="Bullet" TargetType="Ellipse">
          <Setter Property="Fill" Value="Black" />
          <Setter Property="Width" Value="6" />
          <Setter Property="Height" Value="6" />
          <Setter Property="Margin" Value="-30,0,0,1" />
        </Style>
        <Style x:Key="Link" TargetType="HyperlinkButton">
          <Setter Property="BorderThickness" Value="0" />
          <Setter Property="FontSize" Value="11" />
          <Setter Property="Margin" Value="-15,-11" />
        </Style>
      </RichTextBlock.Resources>
      <xsl:if test="normalize-space(text()) != ''">
        <Paragraph><xsl:value-of select="normalize-space(text())" /></Paragraph>
      </xsl:if>
      <xsl:apply-templates select="/div/*" />
    </RichTextBlock>
  </xsl:template>
  <xsl:template match="div" priority="0">
    <Span><xsl:apply-templates /></Span>
  </xsl:template>

  <!-- XAML Paragraphs cannot contain paragraphs, so we convert top-level html paragraphs to xaml paragraphs and convert nested html paragraphs to xaml spans with linebreaks -->
  <xsl:template match="/div/P | /div/p" priority="9">
    <Paragraph><xsl:apply-templates /></Paragraph>
  </xsl:template>
  <xsl:template match="P | p" priority="0">
    <Span><LineBreak /><xsl:apply-templates /><LineBreak /></Span>
  </xsl:template>

  <!-- The RichTextBlock XAML element can contain only paragraph child elements, so any unknown html child elements of the root element will become XAML paragraphs -->
  <xsl:template match="/div/*">
    <Paragraph><xsl:apply-templates /></Paragraph>
  </xsl:template>

  <!-- Lists can only occur outside paragraphs, at the top level -->
  <xsl:template match="/div/UL | /div/ul"><xsl:apply-templates /></xsl:template>

  <xsl:template match="/div/UL/LI | /div/ul/LI | /div/UL/li | /div/ul/li" priority="9" >
    <Paragraph Margin="20,0,0,0"><Span><InlineUIContainer><Ellipse Style="{{StaticResource Bullet}}"/></InlineUIContainer><xsl:apply-templates /><LineBreak /></Span></Paragraph>
  </xsl:template>
  <!-- An UL can only contain LI, so ignore all other elements within an UL -->
  <xsl:template match="/div/UL/* | /div/ul/*" priority="8" />

  <xsl:template match="B | b | STRONG | strong">
    <Bold><xsl:apply-templates /></Bold>
  </xsl:template>

  <xsl:template match="I | i">
    <Italic><xsl:apply-templates /></Italic>
  </xsl:template>

  <xsl:template match="U | u">
    <Underline><xsl:apply-templates /></Underline>
  </xsl:template>

  <xsl:template match="BR | br" priority="0" >
    <LineBreak />
  </xsl:template>

  <xsl:template match="A | a">
    <Span><InlineUIContainer><HyperlinkButton Style="{{StaticResource Link}}"><xsl:attribute name="NavigateUri"><xsl:value-of select="@href"/></xsl:attribute><xsl:apply-templates /></HyperlinkButton></InlineUIContainer></Span>
  </xsl:template>

  <xsl:template match="IMG | img">
    <Span><InlineUIContainer><Image Stretch="None" ><xsl:attribute name="Source"><xsl:value-of select="@src"/></xsl:attribute><xsl:apply-templates /></Image></InlineUIContainer></Span>
  </xsl:template>

  <!-- Note that by default, the text content of any unmatched HTML elements will be copied in the XAML. -->
</xsl:stylesheet>

RichTextBlockProperties.cs

public class Properties : DependencyObject
    {
        public static readonly DependencyProperty HtmlProperty =
            DependencyProperty.RegisterAttached("Html", typeof(string), typeof(Properties), new PropertyMetadata(null, HtmlChanged));

        /// <summary>
        /// sets the HTML property
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetHtml(DependencyObject obj, string value)
        {
            obj.SetValue(HtmlProperty, value);
        }

        /// <summary>
        /// Gets the HTML property
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetHtml(DependencyObject obj)
        {
            return (string)obj.GetValue(HtmlProperty);
        }

        /// <summary>
        /// This is called when the HTML has changed so that we can generate RT content
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void HtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RichTextBlock richText = d as RichTextBlock;
            if (richText == null) return;

            //Generate blocks
            string xhtml = e.NewValue as string;

            string baselink = "http://52.70.18.77:82";

            List<Block> blocks = GenerateBlocksForHtml(xhtml, baselink);

            //Add the blocks to the RichTextBlock
            try
            {
                richText.Blocks.Clear();
                foreach (Block b in blocks)
                {
                    richText.Blocks.Add(b);
                }
            }
            catch (Exception)
            {

                Debug.WriteLine("problems with richtextblock!");
            }

        }

        private static List<Block> GenerateBlocksForHtml(string xhtml, string baselink)
        {
            List<Block> bc = new List<Block>();

            try
            {
                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(xhtml);

                foreach (HtmlNode img in doc.DocumentNode.Descendants("img"))
                {
                    if (!img.Attributes["src"].Value.StartsWith("http"))
                    {
                        img.Attributes["src"].Value = baselink + img.Attributes["src"].Value;
                    }
                }

                Block b = GenerateParagraph(doc.DocumentNode);
                bc.Add(b);
            }
            catch (Exception ex)
            {
            }

            return bc;
        }

        /// <summary>
        /// Cleans HTML text for display in paragraphs
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private static string CleanText(string input)
        {
            string clean = Windows.Data.Html.HtmlUtilities.ConvertToText(input);
            //clean = System.Net.WebUtility.HtmlEncode(clean);
            if (clean == "\0")
                clean = "\n";
            return clean;
        }

        private static Block GenerateBlockForTopNode(HtmlNode node)
        {
            return GenerateParagraph(node);
        }


        private static void AddChildren(Paragraph p, HtmlNode node)
        {
            bool added = false;
            foreach (HtmlNode child in node.ChildNodes)
            {
                Inline i = GenerateBlockForNode(child);
                if (i != null)
                {
                    p.Inlines.Add(i);
                    added = true;
                }
            }
            if (!added)
            {
                p.Inlines.Add(new Run() { Text = CleanText(node.InnerText) });
            }
        }

        private static void AddChildren(Span s, HtmlNode node)
        {
            bool added = false;

            foreach (HtmlNode child in node.ChildNodes)
            {
                Inline i = GenerateBlockForNode(child);
                if (i != null)
                {
                    s.Inlines.Add(i);
                    added = true;
                }
            }
            if (!added)
            {
                s.Inlines.Add(new Run() { Text = CleanText(node.InnerText) });
            }
        }

        private static Inline GenerateBlockForNode(HtmlNode node)
        {
            switch (node.Name)
            {
                case "div":
                    return GenerateSpan(node);
                case "p":
                case "P":
                    return GenerateInnerParagraph(node);
                case "img":
                case "IMG":
                    return GenerateImage(node);
                case "a":
                case "A":
                    if (node.ChildNodes.Count >= 1 && (node.FirstChild.Name == "img" || node.FirstChild.Name == "IMG"))
                        return GenerateImage(node.FirstChild);
                    else
                        return GenerateHyperLink(node);
                case "li":
                case "LI":
                    return GenerateLI(node);
                case "b":
                case "B":
                    return GenerateBold(node);
                case "em":
                case "EM":
                case "i":
                case "I":
                    return GenerateItalic(node);
                case "u":
                case "U":
                    return GenerateUnderline(node);
                case "br":
                case "BR":
                    return new LineBreak();
                case "span":
                case "Span":
                    return GenerateSpan(node);
                case "iframe":
                case "Iframe":
                    return GenerateIFrame(node);
                case "embed":
                case "Embed":
                    return GenerateIFrame(node);
                case "#text":
                    if (!string.IsNullOrWhiteSpace(node.InnerText))
                        return new Run() { Text = CleanText(node.InnerText) };
                    break;
                case "h1":
                case "H1":
                    return GenerateH1(node);
                case "h2":
                case "H2":
                    return GenerateH2(node);
                case "h3":
                case "H3":
                    return GenerateH3(node);
                case "ul":
                case "UL":
                    return GenerateUL(node);
                default:
                    return GenerateSpanWNewLine(node);
            }
            return null;
        }

        private static Inline GenerateLI(HtmlNode node)
        {
            Span s = new Span();
            InlineUIContainer iui = new InlineUIContainer();
            Ellipse ellipse = new Ellipse();
            ellipse.Fill = new SolidColorBrush(Colors.Black);
            ellipse.Width = 6;
            ellipse.Height = 6;
            ellipse.Margin = new Thickness(-30, 0, 0, 1);
            iui.Child = ellipse;
            s.Inlines.Add(iui);
            AddChildren(s, node);
            s.Inlines.Add(new LineBreak());
            return s;
        }

        private static Inline GenerateImage(HtmlNode node)
        {
            Span s = new Span();
            try
            {
                InlineUIContainer iui = new InlineUIContainer();
                var sourceUri = System.Net.WebUtility.HtmlDecode(node.Attributes["src"].Value);
                Image img = new Image() { Source = new BitmapImage(new Uri(sourceUri, UriKind.Absolute)) };
                img.Stretch = Stretch.Uniform;
                img.VerticalAlignment = VerticalAlignment.Center;
                img.HorizontalAlignment = HorizontalAlignment.Center;
                img.Width = Window.Current.Bounds.Width - 15;
                iui.Child = img;
                s.Inlines.Add(iui);
            }
            catch (Exception ex)
            {
            }
            return s;
        }

        private static Inline GenerateHyperLink(HtmlNode node)
        {
            Span s = new Span();
            InlineUIContainer iui = new InlineUIContainer();

            Debug.WriteLine(node.Attributes["href"].Value);
            HyperlinkButton hb;
            string lk = node.Attributes["href"].Value;
            if (!lk.Contains("http"))
            {
                //lk = string.Format("http://cc.com/{0}", lk);
            }
            hb = new HyperlinkButton() { NavigateUri = new Uri(lk, UriKind.RelativeOrAbsolute), Content = CleanText(node.InnerText), };

            if (node.ParentNode != null && (node.ParentNode.Name == "li" || node.ParentNode.Name == "LI"))
                hb.Style = (Style)Application.Current.Resources["RTLinkLI"];
            else if ((node.NextSibling == null || string.IsNullOrWhiteSpace(node.NextSibling.InnerText)) && (node.PreviousSibling == null || string.IsNullOrWhiteSpace(node.PreviousSibling.InnerText)))
                hb.Style = (Style)Application.Current.Resources["RTLinkOnly"];
            else
                hb.Style = (Style)Application.Current.Resources["RTLink"];

            iui.Child = hb;

            s.Inlines.Add(iui);

            return s;
        }

        private static Inline GenerateIFrame(HtmlNode node)
        {
            try
            {
                Span s = new Span();
                s.Inlines.Add(new LineBreak());
                InlineUIContainer iui = new InlineUIContainer();

                int height = 160;
                int width = 300;

                WebView ww = new WebView()
                {
                    Source = new Uri(node.Attributes["src"].Value, UriKind.Absolute)
                    ,
                    Width = width,
                    Height = height
                };

                iui.Child = ww;
                s.Inlines.Add(iui);
                s.Inlines.Add(new LineBreak());
                return s;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private static Block GenerateTopIFrame(HtmlNode node)
        {
            try
            {
                Paragraph p = new Paragraph();
                InlineUIContainer iui = new InlineUIContainer();
                WebView ww = new WebView()
                {
                    Source = new Uri(node.Attributes["src"].Value, UriKind.Absolute)
                    ,
                    Width = Int32.Parse(node.Attributes["width"].Value),
                    Height = Int32.Parse(node.Attributes["height"].Value)
                };
                iui.Child = ww;
                p.Inlines.Add(iui);
                return p;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private static Inline GenerateBold(HtmlNode node)
        {
            Bold b = new Bold();
            AddChildren(b, node);
            return b;
        }

        private static Inline GenerateUnderline(HtmlNode node)
        {
            Underline u = new Underline();
            AddChildren(u, node);
            return u;
        }

        private static Inline GenerateItalic(HtmlNode node)
        {
            Italic i = new Italic();
            AddChildren(i, node);
            return i;
        }

        private static Block GenerateParagraph(HtmlNode node)
        {
            Paragraph p = new Paragraph();
            AddChildren(p, node);
            return p;
        }

        private static Inline GenerateUL(HtmlNode node)
        {
            Span s = new Span();
            s.Inlines.Add(new LineBreak());
            AddChildren(s, node);
            return s;
        }

        private static Inline GenerateInnerParagraph(HtmlNode node)
        {
            Span s = new Span();
            s.Inlines.Add(new LineBreak());
            AddChildren(s, node);
            s.Inlines.Add(new LineBreak());
            return s;
        }

        private static Inline GenerateSpan(HtmlNode node)
        {
            Span s = new Span();
            AddChildren(s, node);
            return s;
        }

        private static Inline GenerateSpanWNewLine(HtmlNode node)
        {
            Span s = new Span();
            AddChildren(s, node);
            if (s.Inlines.Count > 0)
                s.Inlines.Add(new LineBreak());
            return s;
        }

        private static Span GenerateH3(HtmlNode node)
        {
            Span s = new Span() { FontSize = (double)Application.Current.Resources["H3"] };
            s.Inlines.Add(new LineBreak());
            Bold bold = new Bold();
            Run r = new Run() { Text = CleanText(node.InnerText) };
            bold.Inlines.Add(r);
            s.Inlines.Add(bold);
            s.Inlines.Add(new LineBreak());
            return s;
        }

        private static Inline GenerateH2(HtmlNode node)
        {
            Span s = new Span() { FontSize = (double)Application.Current.Resources["H2"] };
            s.Inlines.Add(new LineBreak());
            Run r = new Run() { Text = CleanText(node.InnerText) };
            s.Inlines.Add(r);
            s.Inlines.Add(new LineBreak());
            return s;
        }

        private static Inline GenerateH1(HtmlNode node)
        {
            Span s = new Span() { FontSize = (double)Application.Current.Resources["H1"] };
            s.Inlines.Add(new LineBreak());
            Run r = new Run() { Text = CleanText(node.InnerText) };
            s.Inlines.Add(r);
            s.Inlines.Add(new LineBreak());
            return s;
        }
    }

我使用下面的代码段来绑定视频标记

private static Inline GenerateIFrame(HtmlNode node)
        {
            try
            {
                Span s = new Span();
                s.Inlines.Add(new LineBreak());
                InlineUIContainer iui = new InlineUIContainer();

                int height = 160;
                int width = 300;

                WebView ww = new WebView()
                {
                    Source = new Uri(node.Attributes["src"].Value, UriKind.Absolute)
                    ,
                    Width = width,
                    Height = height
                };

                iui.Child = ww;
                s.Inlines.Add(iui);
                s.Inlines.Add(new LineBreak());
                return s;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

但是视频没有绑定。它只是根据高度来确定空间。请有人指导在富文本框控件中绑定视频标记

非常感谢任何有关此方面的帮助

0 个答案:

没有答案