nev*_*out 7 c# wpf richtextbox flowdocument
基本上,我有一个RichTextBox,我想将它的格式化内容转换为HTML,以便它可以作为电子邮件发送.
我目前使用的方法根本不提供任何格式:
string message = new TextRange(messageTextBox.Document.ContentStart,
messageTextBox.Document.ContentEnd).Text;
Run Code Online (Sandbox Code Playgroud)
所以我四处搜索并发现了这一点,然而,它已经超过5年了,在评论中,MSFT用户评论说它不再受支持 - "This sample has been removed from our sample set and is no longer supported"
并且它生成的HTML格式比现代HTML或XHTML更旧.有更好的.
任何人都可以告诉我如何将RichTextBox 的格式化内容转换为HTML?
(因此,当发送电子邮件时,收件人会看到带有格式的电子邮件)
Rob*_*ney 13
一般技术是使用a XamlWriter
将FlowDocument
内容转换为XML流,然后使用XSLT转换将XML转换为HTML.这不是一个答案,但那是因为任何给定的FlowDocument都有大量可能的HTML表示.
这种变换,例如,每个顶级转换Section
到div
每一个,Paragraph
来一个p
,每Run
一个span
,它的类会告诉你是否它的斜体字,粗体或加下划线,或任何以上的组合.它对我写的目的很有用,但称之为有损转换是轻描淡写的:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl x">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="x:Section[not(parent::x:Section)]">
<div>
<xsl:apply-templates select="node()"/>
</div>
</xsl:template>
<xsl:template match="x:Section">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="x:Paragraph">
<p>
<xsl:apply-templates select="node()"/>
</p>
</xsl:template>
<xsl:template match="x:Run">
<xsl:variable name="class">
<xsl:if test="@FontStyle='Italic'">
<xsl:text>i </xsl:text>
</xsl:if>
<xsl:if test="@FontWeight='Bold'">
<xsl:text>b </xsl:text>
</xsl:if>
<xsl:if test="contains(@TextDecorations, 'Underline')">
<xsl:text>u </xsl:text>
</xsl:if>
</xsl:variable>
<span>
<xsl:if test="normalize-space($class) != ''">
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($class)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="text()"/>
</span>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
这是我编写的用于转换的值转换器 - 请注意,为了使用值转换器,您还必须破解并实现一个版本RichTextBox
,将内容公开为依赖属性.真的,整个项目都很痛苦.
public class FlowDocumentToHtmlConverter : IValueConverter
{
private static XslCompiledTransform ToHtmlTransform;
private static XslCompiledTransform ToXamlTransform;
public FlowDocumentToHtmlConverter()
{
if (ToHtmlTransform == null)
{
ToHtmlTransform = LoadTransformResource("Converters/FlowDocumentToXhtml.xslt");
}
if (ToXamlTransform == null)
{
ToXamlTransform = LoadTransformResource("Converters/XhtmlToFlowDocument.xslt");
}
}
private static XslCompiledTransform LoadTransformResource(string path)
{
Uri uri = new Uri(path, UriKind.Relative);
XmlReader xr = XmlReader.Create(Application.GetResourceStream(uri).Stream);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xr);
return xslt;
}
#region IValueConverter Members
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is FlowDocument))
{
return null;
}
if (targetType == typeof(FlowDocument))
{
return value;
}
if (targetType != typeof(string))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert back from a FlowDocument to a string.");
}
FlowDocument d = (FlowDocument)value;
using (MemoryStream ms = new MemoryStream())
{
// write XAML out to a MemoryStream
TextRange tr = new TextRange(
d.ContentStart,
d.ContentEnd);
tr.Save(ms, DataFormats.Xaml);
ms.Seek(0, SeekOrigin.Begin);
// transform the contents of the MemoryStream to HTML
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
XmlReader xr = XmlReader.Create(ms);
XmlWriter xw = XmlWriter.Create(sw, xws);
ToHtmlTransform.Transform(xr, xw);
}
return sb.ToString();
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
{
return new FlowDocument();
}
if (value is FlowDocument)
{
return value;
}
if (targetType != typeof(FlowDocument))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert to a FlowDocument.");
}
if (!(value is string))
{
throw new InvalidOperationException(
"FlowDocumentToHtmlConverter can only convert from a string or FlowDocument.");
}
string s = (string)value;
FlowDocument d;
using (MemoryStream ms = new MemoryStream())
using (StringReader sr = new StringReader(s))
{
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
using (XmlReader xr = XmlReader.Create(sr))
using (XmlWriter xw = XmlWriter.Create(ms, xws))
{
ToXamlTransform.Transform(xr, xw);
}
ms.Seek(0, SeekOrigin.Begin);
d = XamlReader.Load(ms) as FlowDocument;
}
XamlWriter.Save(d, Console.Out);
return d;
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8164 次 |
最近记录: |