wpf - loading ResourceDictionary from baml using Baml2006Reader -


how can read through baml stream contains resourcedictionaory using baml2006reader , without acually instantiating the resourcedictionary?

i can ready through regular baml contains usercontrol fine , can examine xaml tree using baml2006reader.nodetype etc.

but once reader hits resourcedictionary, baml2006reader.member.name "deferrablecontent" , baml2006reader.value contains memorystream can not parsed instance of baml2006reader. can't event instantiate reader:

system.io.endofstreamexception occurred hresult=-2147024858
message=unable read beyond end of stream. source=mscorlib stacktrace: @ system.io.memorystream.internalreadint32() @ system.windows.baml2006.baml2006reader.process_header() @ wpfapplication10.assemblyextensions.read(stream stream, list`1 result) in d:\documents\visual studio 2012\projects\wpfapplication10\wpfapplication10\assemblyextensions.cs:line 84 innerexception:

it seems whenever baml2006reader encounters element baml2006reader.member.name "deferrablecontent" followed node bamlreader.value memorystream. seems stream contains baml fragment , not have header (that's why system.windows.baml2006.baml2006reader.process_header() fails.)

so need tell baml reader read baml fragment. can done giving reader instance of system.windows.baml2006.baml2006readersettings isbamlfragment property istrue.

unfortunately both baml2006readersettings class , appropriate constructor of baml2006reader internal. need resort reflection:

private static string presentationframeworkassemblyname = "presentationframework, version=4.0.0.0, culture=neutral, publickeytoken=31bf3856ad364e35";  private static baml2006reader createbamlfragmentreader(memorystream substream, xamlschemacontext schemacontext) {     var bamlsettingstype =         type.gettype(             "system.windows.baml2006.baml2006readersettings, " + presentationframeworkassemblyname);     var settingsctor =         bamlsettingstype.getconstructor(type.emptytypes);     var bamlsettings = settingsctor.invoke(null);     var isbamlfragmentprop = bamlsettingstype.getproperty("isbamlfragment",                                                               bindingflags.nonpublic |                                                               bindingflags.instance);     isbamlfragmentprop.setvalue(bamlsettings, true, null);      var ctor = typeof (baml2006reader).getconstructor(         bindingflags.instance | bindingflags.nonpublic,         null,         new[]         {             typeof (stream),             type.gettype(                 "system.windows.baml2006.baml2006schemacontext, " + presentationframeworkassemblyname),                 bamlsettingstype             },             null);          return (baml2006reader)ctor.invoke(new[] { substream, schemacontext, bamlsettings });     } 

usage:

var substream = reader.value memorystream; if (substream != null) {     using (var subreader = createbamlfragmentreader(substream, reader.schemacontext))     {         // continue reading subreader     } } 

i know rather fragile code , hackish, heck - works (for me, currently)!


Comments

Popular posts from this blog

curl - PHP fsockopen help required -

HTTP/1.0 407 Proxy Authentication Required PHP -

c# - Resource not found error -