如何读取包含使用ResourceDictionaory的Baml2006Reader的baml流,而不随意实例化ResourceDictionary?
我可以通过只包含UserControl的常规baml做好准备,我可以使用Baml2006Reader.NodeType等来检查XAML树。
但是一旦读者点击了ResourceDictionary,Baml2006Reader.Member.Name就是"DeferrableContent",Baml2006Reader.Value包含一个不能被Baml2006Reader的另一个实例解析的MemoryStream。我不能实例化阅读器:
System.IO.EndOfStreamException发生HResult=-2147024858 Message=Unable读取流结束后的内容。System.Windows.Baml2006.Baml2006Reader.Process_Header() at WpfApplication10.AssemblyExtensions.Read(Stream流的Source=mscorlib StackTrace: d:\d\Visual 2012\Projects\WpfApplication10\WpfApplication10\AssemblyExtensions.cs:line 84 InnerException中的清单1结果:
发布于 2013-07-29 11:48:03
似乎每当Baml2006Reader遇到Baml2006Reader.Member.Name是"DeferrableContent"的元素时,就会跟着另一个节点,其中BamlReader.Value是MemoryStream。这个流似乎只包含一个baml片段,并且没有头(这就是为什么System.Windows.Baml2006.Baml2006Reader.Process_Header()失败的原因)。
所以我们需要告诉baml读取器读取baml片段。这可以为读者提供System.Windows.Baml2006.Baml2006ReaderSettings的一个实例,其中IsBamlFragment属性是true。
不幸的是,Baml2006ReaderSettings类和Baml2006Reader的适当构造函数都是内部的。因此,我们需要进行反思:
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 });
}用法:
var substream = reader.Value as MemoryStream;
if (substream != null)
{
using (var subReader = CreateBamlFragmentReader(substream, reader.SchemaContext))
{
// continue reading with subReader
}
}我知道这是相当脆弱的代码和非常黑客,但什么见鬼-它的工作(对我,目前)!
https://stackoverflow.com/questions/17860794
复制相似问题