我需要绑定一个在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;
}
}
但是视频没有绑定。它只是根据高度来确定空间。请有人指导在富文本框控件中绑定视频标记
非常感谢任何有关此方面的帮助