首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ResourceDictionary从baml加载Baml2006Reader

使用ResourceDictionary从baml加载Baml2006Reader
EN

Stack Overflow用户
提问于 2013-07-25 14:24:59
回答 1查看 1.1K关注 0票数 0

如何读取包含使用ResourceDictionaoryBaml2006Reader的baml流,而不随意实例化ResourceDictionary

我可以通过只包含UserControl的常规baml做好准备,我可以使用Baml2006Reader.NodeType等来检查XAML树。

但是一旦读者点击了ResourceDictionaryBaml2006Reader.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结果:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-29 11:48:03

似乎每当Baml2006Reader遇到Baml2006Reader.Member.Name"DeferrableContent"的元素时,就会跟着另一个节点,其中BamlReader.ValueMemoryStream。这个流似乎只包含一个baml片段,并且没有头(这就是为什么System.Windows.Baml2006.Baml2006Reader.Process_Header()失败的原因)。

所以我们需要告诉baml读取器读取baml片段。这可以为读者提供System.Windows.Baml2006.Baml2006ReaderSettings的一个实例,其中IsBamlFragment属性是true

不幸的是,Baml2006ReaderSettings类和Baml2006Reader的适当构造函数都是内部的。因此,我们需要进行反思:

代码语言:javascript
复制
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 });
    }

用法:

代码语言:javascript
复制
var substream = reader.Value as MemoryStream;
if (substream != null)
{
    using (var subReader = CreateBamlFragmentReader(substream, reader.SchemaContext))
    {
        // continue reading with subReader
    }
}

我知道这是相当脆弱的代码和非常黑客,但什么见鬼-它的工作(对我,目前)!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17860794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档