首页 > 解决方案 > WPF - 如何从 Pack URI 获取控件的代码隐藏类型定义?

问题描述

WPF 中是否有保留此数据的方法或映射?我想传递 URI 并获得一个类型作为回报?

我知道Application.GetResourceStream(URI),但这会返回 BAML 流。

提前致谢。

标签: c#wpf

解决方案


经过一番研究,我没有找到任何从 URI 返回基础类型的方法。

URI 所做的只是指向嵌入在某个程序集中的资源,我通过手动提取资源得到了我需要的东西:

public static Type GetTypeFromUri(Uri uri)
{
    Type type = null;
    using (var stream = Application.GetResourceStream(uri).Stream)
    using (var reader = new Baml2006Reader(stream))
    {
        while (reader.Read())
        {
            if (reader.Type != null)
            {
                type = reader.Type.UnderlyingType;
                break;
            }
        }
    }

    return type;
}

以下代码适用于一些假设:

  • XAML 资源的构建操作设置为 Page(它被编译为 BAML) 在此处输入图像描述
  • Baml2006Reader 找到的第一个类型是 Code-Behind 类型(例如,如果一个类没有像 ResourceDictionary 这样的 Code-Behind 类型,您将获得 ResourceDictionary 作为 Type )。我不太熟悉 BAML 的结构,但一些测试表明情况确实如此。

测试表明阅读器首先解析包含的命名空间,然后是代码隐藏类型,因此reader.Read()调用了几次迭代(其中 reader.Type 为空,但 reader.Namespace 已填充 - 我们不需要),然后是我们需要的部分。

如果我们继续读取流,它将遍历可视化树,并解析子类型。

由于维基百科是这样说的:

在运行时,框架引擎从程序集资源中提取 .BAML 文件,对其进行解析,并创建相应的 WPF 可视化树或工作流。

我相信这是正确的做法。

如果您认为这不是最有效的方法,或者应该做得更好,请给出新的答案。


推荐阅读