将 MemoryStream 中的 RTF 内容附加到 XamRichTextEditor 中的最简单方法是什么
What's the easiest way to append RTF content from a MemoryStream into an XamRichTextEditor
我正在尝试合并来自标准 System.Windows.Controls.RichTextBox 控件的 RTF 上下文,并将其附加到 XamRichTextEditor 控件的当前 RTF 上下文的末尾。目前,我的以下代码在我尝试引用临时 XamRichTextEditor 的 "ActiveDocumentView" 的第一行抛出空引用异常,尽管我假设在调用 Document.Load 之后它应该被初始化并填充内容。我愿意用不同的方法来解决这个问题,Copy/Paste 的想法似乎是最简单的。
代码:
byte[] byteSig = Encoding.ASCII.GetBytes(rtfContextText);
using (MemoryStream ms = new MemoryStream(byteSig))
{
XamRichTextEditor tmpRichTextBox = new XamRichTextEditor();
tmpRichTextBox.Document.Load(RtfSerializationProvider.Instance, ms); // put current email body into memory stream
tmpRichTextBox.ActiveDocumentView.Selection.SelectAll(); // select all content
tmpRichTextBox.ActiveDocumentView.Selection.Copy(); // copy content into Clipboard
txtTextEditor.ActiveDocumentView.Selection.Paste(); // append Clipboard content into main XamRichTextEditor control
}
我能够为我自己的问题构建一个答案,但我永远无法让复制和粘贴方法完全适合我(我将一些内容从一个粘贴到另一个,但换行符结果中嵌入的图像似乎被忽略了)。
我最终不得不直接手动处理 2 个 RichTextBox 上下文的原始数据。为此,我在 Target 上下文中找到了我想插入另一个的位置,并从另一个上下文中剥离了除最外层分组以外的所有分组(以避免重复根节点)。然后,我用这个串联版本加载了 Target RichTextBox 的文档。 (下面的示例代码适用于 运行 遇到我遇到的同一问题的任何人。希望它最终能帮助别人。)
// get string encoded version of body
using (MemoryStream ms = new MemoryStream())
{
txtTextEditor.Document.Save(RtfSerializationProvider.Instance, ms);
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms))
{
strRtfCurrBody = sr.ReadToEnd();
}
}
// find end and then the beginning of second-to-last grouping
strRtfSignature = strRtfSignature.Remove(strRtfSignature.LastIndexOf('}'));
int intCheck = PibsEmailer.RtfFindStartpoint(strRtfSignature, strRtfSignature.LastIndexOf('}'));
if (intCheck < 0)
{
// this should never happen unless the content of the signature is not in valid RTF format
throw new Exception("AddSignature Failed. Sig=\"" + Session.CurrentUser.EmailSignature + "\" , Body=\"" + strRtfCurrBody + "\" IntCheck=" + intCheck);
}
strRtfSignature = strRtfSignature.Substring(intCheck);
strRtfCurrBody = strRtfCurrBody.Insert(PibsEmailer.RtfFindLastParEnd(strRtfCurrBody), strRtfSignature);
byte[] byteFullContent = Encoding.ASCII.GetBytes(strRtfCurrBody);
using (MemoryStream ms = new MemoryStream(byteFullContent))
{
ms.Seek(0, SeekOrigin.Begin);
this.txtTextEditor.Selection.SelectAll();
this.txtTextEditor.Selection.Document.Load(RtfSerializationProvider.Instance, ms);
}
为了帮助处理 RTF 格式的数据,我编写了以下两个函数(在上面的代码中引用):
public static int RtfFindLastParEnd(string source)
{
int intLastPar = source.LastIndexOf("par}");
if (intLastPar > 0)
{
intLastPar += 4; // add offset of "par}"
}
return intLastPar;
}
public static int RtfFindStartpoint(string source, int indexOfClosingBrace)
{
string workingString = source;
int nestCount = 0;
int currIndex = indexOfClosingBrace;
while (currIndex > 0)
{
if (source[currIndex] == '}')
nestCount++;
else if (source[currIndex] == '{')
nestCount--;
if (nestCount == 0)
{
return currIndex;
}
currIndex--;
}
return -1;
}
我正在尝试合并来自标准 System.Windows.Controls.RichTextBox 控件的 RTF 上下文,并将其附加到 XamRichTextEditor 控件的当前 RTF 上下文的末尾。目前,我的以下代码在我尝试引用临时 XamRichTextEditor 的 "ActiveDocumentView" 的第一行抛出空引用异常,尽管我假设在调用 Document.Load 之后它应该被初始化并填充内容。我愿意用不同的方法来解决这个问题,Copy/Paste 的想法似乎是最简单的。
代码:
byte[] byteSig = Encoding.ASCII.GetBytes(rtfContextText);
using (MemoryStream ms = new MemoryStream(byteSig))
{
XamRichTextEditor tmpRichTextBox = new XamRichTextEditor();
tmpRichTextBox.Document.Load(RtfSerializationProvider.Instance, ms); // put current email body into memory stream
tmpRichTextBox.ActiveDocumentView.Selection.SelectAll(); // select all content
tmpRichTextBox.ActiveDocumentView.Selection.Copy(); // copy content into Clipboard
txtTextEditor.ActiveDocumentView.Selection.Paste(); // append Clipboard content into main XamRichTextEditor control
}
我能够为我自己的问题构建一个答案,但我永远无法让复制和粘贴方法完全适合我(我将一些内容从一个粘贴到另一个,但换行符结果中嵌入的图像似乎被忽略了)。
我最终不得不直接手动处理 2 个 RichTextBox 上下文的原始数据。为此,我在 Target 上下文中找到了我想插入另一个的位置,并从另一个上下文中剥离了除最外层分组以外的所有分组(以避免重复根节点)。然后,我用这个串联版本加载了 Target RichTextBox 的文档。 (下面的示例代码适用于 运行 遇到我遇到的同一问题的任何人。希望它最终能帮助别人。)
// get string encoded version of body
using (MemoryStream ms = new MemoryStream())
{
txtTextEditor.Document.Save(RtfSerializationProvider.Instance, ms);
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms))
{
strRtfCurrBody = sr.ReadToEnd();
}
}
// find end and then the beginning of second-to-last grouping
strRtfSignature = strRtfSignature.Remove(strRtfSignature.LastIndexOf('}'));
int intCheck = PibsEmailer.RtfFindStartpoint(strRtfSignature, strRtfSignature.LastIndexOf('}'));
if (intCheck < 0)
{
// this should never happen unless the content of the signature is not in valid RTF format
throw new Exception("AddSignature Failed. Sig=\"" + Session.CurrentUser.EmailSignature + "\" , Body=\"" + strRtfCurrBody + "\" IntCheck=" + intCheck);
}
strRtfSignature = strRtfSignature.Substring(intCheck);
strRtfCurrBody = strRtfCurrBody.Insert(PibsEmailer.RtfFindLastParEnd(strRtfCurrBody), strRtfSignature);
byte[] byteFullContent = Encoding.ASCII.GetBytes(strRtfCurrBody);
using (MemoryStream ms = new MemoryStream(byteFullContent))
{
ms.Seek(0, SeekOrigin.Begin);
this.txtTextEditor.Selection.SelectAll();
this.txtTextEditor.Selection.Document.Load(RtfSerializationProvider.Instance, ms);
}
为了帮助处理 RTF 格式的数据,我编写了以下两个函数(在上面的代码中引用):
public static int RtfFindLastParEnd(string source)
{
int intLastPar = source.LastIndexOf("par}");
if (intLastPar > 0)
{
intLastPar += 4; // add offset of "par}"
}
return intLastPar;
}
public static int RtfFindStartpoint(string source, int indexOfClosingBrace)
{
string workingString = source;
int nestCount = 0;
int currIndex = indexOfClosingBrace;
while (currIndex > 0)
{
if (source[currIndex] == '}')
nestCount++;
else if (source[currIndex] == '{')
nestCount--;
if (nestCount == 0)
{
return currIndex;
}
currIndex--;
}
return -1;
}