我正在尝试创建一个应用程序,我可以在其中将文本和图像输入到 RichTextBox 中,对其进行序列化,然后将其反序列化并将其加载回 RichTextBox,以便我以后可以更改它。当我从序列化的 xml 文件加载图像时,一切都正确显示,但是当我尝试通过按退格键手动从 RichTextBox 中删除图像时,出现以下异常:无法序列化非公共(public)类型 'System.Windows.Media .Imaging.BitmapFrameDecode'。
下面是我如何从 RichTextBox 中提取和存储数据。它会检查所有的 block ,如果它找到一个图像,那么它只是在列表文本中保存一个占位符字符串,这样当它返回时它就会知道将图像放回那个位置:
public void GetFindingsData(FlowDocument flowDoc, List<string> text, List<byte[]> bytes)
{
foreach (Block block in flowDoc.Blocks)
{
if (block.GetType() == typeof(Paragraph))
{
foreach (Run run in ((Paragraph)block).Inlines)
{
text.Add(run.Text);
}
}
else if (block.GetType() == typeof(BlockUIContainer) && ((BlockUIContainer)block).Child.GetType() == typeof(Image))
{
Image img = (Image)((BlockUIContainer)block).Child;
bytes.Add(Storage.ImageToByteArray(img));
text.Add("imageplaceholder_" + (bytes.Count - 1).ToString());
}
}
}
下面是我如何将该数据放回 FlowDocument 以在 RichTextBox 中显示:
public FlowDocument createFlowDocument(List<string> runs, List<byte[]> bytes)
{
FlowDocument flowDoc = new FlowDocument();
int counter = 0;
foreach (string run in runs)
{
if (run == "imageplaceholder_" + counter.ToString())
{
flowDoc.Blocks.Add(new BlockUIContainer(Storage.ByteArrayToImage(bytes[counter])));
counter++;
}
else
{
Paragraph par = new Paragraph();
par.Inlines.Add(run);
flowDoc.Blocks.Add(par);
}
}
return flowDoc;
}
如果您需要,下面是我如何序列化 RichTextBox 中的数据。我的所有其他数据都序列化为 xml,但这不适用于图像,因此我首先将其序列化为字节数组:
public static byte[] ImageToByteArray(Image image)
{
byte[] imageBuffer = null;
if (image != null)
{
using (var stream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image.Source as BitmapSource));
encoder.Save(stream);
imageBuffer = stream.ToArray();
}
}
return imageBuffer;
}
这是我将所有内容序列化和反序列化到 xml 文件的地方(尽管我认为问题不在这里):
public static void SaveData(StoredData data)
{
XmlSerializer serializer = new XmlSerializer(typeof(StoredData));
using (FileStream stream = new FileStream(readerString, FileMode.Create, FileAccess.Write, FileShare.None))
{
serializer.Serialize(stream, data);
}
}
public static StoredData LoadData()
{
try
{
StoredData storedData = new StoredData();
using (FileStream stream = new FileStream(readerString, FileMode.Open))
{
XmlSerializer deserializer = new XmlSerializer(typeof(StoredData));
storedData = (StoredData)deserializer.Deserialize(stream);
}
return storedData;
}
catch
{
StoredData newData = new StoredData();
XmlSerializer serializer = new XmlSerializer(typeof (StoredData));
using (FileStream stream = new FileStream(readerString, FileMode.Create, FileAccess.Write, FileShare.None))
{
serializer.Serialize(stream, newData);
}
return newData;
}
}
下面是我如何从字节数组中取回图像:
public static Image ByteArrayToImage(Byte[] imageBytes)
{
using (MemoryStream stream = new MemoryStream(imageBytes))
{
BitmapDecoder decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
BitmapFrame frame = decoder.Frames.First();
frame.Freeze();
Image newImage = new Image();
newImage.Source = frame;
return newImage;
}
}
如有任何帮助,我们将不胜感激。
最佳答案
当用户从 RichTextBox 中删除图像时,它 copies通过将已删除的项目序列化为 XAML,将它们添加到撤消流中。从堆栈跟踪中可以明显看出这一点:
at System.Windows.Markup.Primitives.MarkupWriter.VerifyTypeIsSerializable(Type type)
at System.Windows.Markup.Primitives.MarkupWriter.WriteItem(MarkupObject item, Scope scope)
at System.Windows.Markup.Primitives.MarkupWriter.WriteItem(MarkupObject item, Scope scope)
at System.Windows.Markup.Primitives.MarkupWriter.WriteItem(MarkupObject item)
at System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml(XmlWriter writer, MarkupObject item)
at System.Windows.Markup.Primitives.MarkupWriter.SaveAsXml(XmlWriter writer, Object instance)
at System.Windows.Markup.XamlWriter.Save(Object obj, TextWriter writer)
at System.Windows.Markup.XamlWriter.Save(Object obj)
at System.Windows.Documents.TextTreeDeleteContentUndoUnit.CopyObjectNode(TextTreeObjectNode objectNode, ContentContainer& container)
at System.Windows.Documents.TextTreeDeleteContentUndoUnit.CopyContent(TextTreeNode node, TextTreeNode haltNode)
at System.Windows.Documents.TextTreeDeleteContentUndoUnit..ctor(TextContainer tree, TextPointer start, TextPointer end)
at System.Windows.Documents.TextTreeUndo.CreateDeleteContentUndoUnit(TextContainer tree, TextPointer start, TextPointer end)
at System.Windows.Documents.TextContainer.DeleteContentInternal(TextPointer startPosition, TextPointer endPosition)
这会给您带来麻烦,因为类型 BitmapFrame是抽象的,BitmapDecoder.Frames.First() 实际返回的类型,BitmapFrameDecode , 是内部的,因此 can't be serialized to XAML .
但是,我不明白您为什么需要使用 BitmapDecoder。为什么不使用常规 BitmapImage ?如果我使用以下代码加载您的图像,现在可以删除插入的图像:
public static Image ByteArrayToImage(Byte[] imageBytes)
{
var stream = new MemoryStream(imageBytes);
{
var frame = new BitmapImage();
frame.BeginInit();
frame.CacheOption = BitmapCacheOption.OnLoad;
frame.StreamSource = stream;
frame.EndInit();
frame.Freeze();
Image newImage = new Image() { Source = frame };
return newImage;
}
}
好吧,这样做之后,我发现了一个次要问题:如果我在删除图像后尝试撤消删除,它就不会回来了。相反,将恢复带有空图像的垃圾 BlockUIContainer。我无法确定发生这种情况的确切原因,但这与 BitmapImage.BaseUri 的事实有关。当 BitmapImage 从内存流而不是从 UriSource 创建时为 null .
反过来,我可以通过序列化到临时 XamlPackage 来解决这个问题:
public static void AddBlockUIContainerImage(this FlowDocument doc, byte[] imageBytes)
{
var image2 = Storage.ByteArrayToImage(imageBytes);
using (var stream = new MemoryStream())
{
var subDoc = new FlowDocument();
subDoc.Blocks.Add(new BlockUIContainer(image2));
new TextRange(subDoc.ContentStart, subDoc.ContentEnd).Save(stream, DataFormats.XamlPackage, true);
stream.Seek(0, SeekOrigin.Begin);
var target = new TextRange(doc.ContentEnd, doc.ContentEnd);
target.Load(stream, DataFormats.XamlPackage);
}
}
完成此操作后,BaseUri 不再为空;撤消、重做、删除、撤消删除和重做删除所有工作。
由于此解决方法意味着您实际上对图像进行了两次反序列化,因此您可能需要考虑将每个图像存储为 XamlPackage 编码字节数组,而不是 Png 编码字节数组。
关于c# - 当我尝试从 WPF 中的 RichTextBox 手动删除图像时出现 InvalidOperationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30239254/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer